在商业 SaaS 项目中使用 Elixir Phoenix

Linkly 是用 Elixir 编写的。

我一直想接触 Erlang 生态系统,而 Elixir 是一条简单的途径。

我不会在这里直接介绍 BEAM 或 Erlang 的好处,因为其他地方已经有很多相关文章。相反,我将专注于在真实项目中使用 Elixir Phoenix 的实际情况。

我将假设你知道 Ruby on Rails 是什么,因为 Phoenix(Elixir 的 Web 框架)深受 Rails 的启发。

在 Elixir Phoenix 中实际编程

用 Elixir 编写代码是一种愉快的体验。

它遵循与 Rails 类似的范式,包括 MVC,甚至看起来也很相似。

与 Rails 不同,代码在运行之前会被编译。这是一个有用的步骤,因为它允许你捕获那些你可能不会注意到的错误。

Phoenix 中的模型被分组为"上下文(Contexts)"。这是一个额外的抽象层,旨在在应用程序的各个部分之间创建清晰的分离,例如用户和产品。每个上下文可以包含任意数量的模型。

性能

其他博客对性能做了很多讨论,所以我将在这里介绍实际方面。

对于一个功能齐全的 Web 框架,性能明显比 Rails 快得多,并且需要的硬件资源要少得多。

运行 mix phx.server 与 rails server 的"启动"时间更快。即使在笔记本电脑上开发,使用 Phoenix 时页面加载速度也明显更快。

Elixir Phoenix 与 Rails 的包可用性

表面上看,这里似乎存在差异。Rails 有数千个 gem,而 Elixir 有 Hex 存储库。

事实上,你实际会使用的几乎所有东西在 Elixir Hex 包系统中都可用 - JSON 解析器、HTTP 客户端、格式化和解析 Markdown 的工具 - 应有尽有,而且模块质量非常出色。

在 Rails 中,有更多的 gem,但你永远不会在真实项目中包含它们,因为它们处于未维护状态,或者在应用程序中构建过多外部依赖的风险。

像 Stripe 和 Recurly 这样的平台维护自己的 Rails gem 来与他们的 API 交互。这可能很方便,但通常缺乏对 Elixir 的支持。

然而,我发现使用 Elixir 的 Tesla 包与服务的 HTTP 端点交互非常容易,最终更喜欢这种工作方式,而不是使用预打包的 gem,因为它更轻量,并且让你能够理解正在发生的事情。

数据库抽象 - Ecto 和 ActiveRecord

Ecto 的功能不如 ActiveRecord 全面。

它本来就不打算如此。

Ecto 是一个简单的数据库包装器,将数据库查询映射到 Elixir 对象。

最初,我发现它不像 ActiveRecord 那样工作让人感到沮丧。

然而,Ecto 让你以一种非常直接的方式与数据库交互,实际上使编写 Web 应用程序变得更加容易。

使用 ActiveRecord,一旦你开始构建复杂的查询,弄清楚 ActiveRecord 所花的时间比直接用 SQL 编写查询还要长。

在使用两者之后,我的结论是使用像 Ecto 这样的轻量级数据库包装器比使用像 ActiveRecord 这样的重量级抽象更容易。

它为你提供了使用数据库包装器的安全性,而没有"过于聪明"的抽象带来的麻烦和负担。

两者都包含迁移和回滚功能。

Phoenix 项目的默认数据库是 Postgres。

对于使用 NoSQL 数据库的用户,Ecto 可以与 Mongo 配合使用。

更好的是,Ecto 可以与 Postgres 的 NoSQL 功能配合使用,允许你在不需要 Mongo 的情况下保存和查询 JSON。

用户认证

这是 Elixir Phoenix 所缺乏的地方。

Rails 有 Devise 模块。Phoenix 有 Coherence,但它目前没有维护。

如果你想使用基本的用户名和密码登录,你必须构建每一个步骤。这包括密码哈希、密码重置逻辑、"记住我"设置等。

这很繁琐,并且带来相当大的安全风险。

我选择使用 Auth0,它与 Phoenix 配合得很好。也许这无论如何都是一个更好的解决方案,但如果有选择的话会更好。

部署和托管

Phoenix 应用的主要托管服务是 Gigalixir,一家由 Elixir 爱好者运营的美国小公司。

Gigalixir 托管在 Google Cloud 上,所以底层基础设施是可靠的。

Gigalixir 的 buildpack 使部署变得容易,并支持所有 Elixir 的智能部署策略(distillery、mix)。

它比"自己动手"更贵,但大部分成本都包含在 Postgres 数据库托管中。

Elixir Phoenix 非常轻量,可以在小型 docker pod 上运行,并且仍然可以处理非常多的请求。

尽管有加价,但绝对值得省去这些麻烦。

我要补充一点,他们的客户支持非常出色。

程序员的可用性

Elixir 程序员要少得多。

Elixir 是一种"程序员的语言" - 一种人们在学习了其他东西之后才接触的语言。

话虽如此,那些使用 Elixir 的人通常是更好的程序员。也许这是有意识地选择一种更好的语言的结果。

这让我想起了 Rails 的早期,当时似乎只有"摇滚明星"才会使用它(相对于 PHP)。

任何优秀的 Rails 程序员都可以轻松掌握 Elixir Phoenix,并在几天内上手运行。

我会再次使用 Elixir Phoenix 吗?

当然会。

我使用过很多语言,Elixir 是我使用过的最简单、最强大的语言。

我期待编写 Elixir。

每月跟踪 500 次点击,包含所有功能。

无需信用卡