2024 年 11 月 7 日,星期四

Rails 8.0:无需 PaaS

作者:dhh

部署现代 Web 应用程序(需要具备快速、安全和易于更新的所有功能)已经变得如此困难,以至于许多开发人员不敢在没有 PaaS(平台即服务)的情况下进行部署。但这太荒谬了。没有人应该仅仅为了让部署变得友好和可用而支付高得多的基本计算成本。这是开源的任务,Rails 8 已经准备好解决它。因此,我们很高兴地宣布,在成功发布 beta 版和多个候选版本后,Rails 8.0 的最终版本现已发布!

以下是所有主要的新功能

Kamal 2 + Thruster 的登场

Rails 8 预先配置了 Kamal 2,用于将您的应用程序部署到任何地方。无论是在云 VM 还是您自己的硬件上。Kamal 只需一个“kamal setup”命令,就可以将一个全新的 Linux 机器变成应用程序或附件服务器。它只需要您 SSH 密钥存储的一组服务器的 IP 地址,您就可以在两分钟内进入生产环境。

Kamal 能够如此轻松地做到这一点,是因为 Rails 已经自带了一个高效且经过调优的 Dockerfile,用于将您的应用程序开箱即用地转换为一个生产就绪的容器镜像。您只需要提供自己的容器注册表帐户,例如 Docker Hub 或 GitHub,用于存储镜像。

在 Rails 8 中,此 Dockerfile 已升级,包含一个名为 Thruster 的新代理,它位于 Puma Web 服务器前面,以提供 X-Sendfile 加速、资产缓存和资产压缩。这意味着不需要在前面放置 Nginx 或任何其他 Web 服务器。默认的 Rails 容器已准备好立即接受来自互联网的流量。

Kamal 2 还包含一个代理,这次是一个定制的单元,称为 Kamal Proxy,以替换它在发布时使用的通用 Traefik 选项。该代理提供超快的零停机时间部署、通过 Let's Encrypt 自动化 SSL 证书,以及在单个服务器上支持多个应用程序,而无需任何复杂的配置。

结合处理秘密的改进策略(包括对 1password、Bitwarden 和 LastPass 的内置集成)和新的别名功能,以获取诸如“kamal console”之类的命令以启动远程 Rails 控制台会话,它提供了一个完整的包,用于处理不仅部署,而且在生产环境中运行您的应用程序。

Kamal 2 由 Donal McBreen 领导,Kamal Proxy + Thruster 由 Kevin McConnell 创作,他们都来自 37signals

显著减少依赖项

使 Rails 更易于部署的一部分是减少开始运行所需的辅助服务数量。过去,Rails 需要 MySQL 或 PostgreSQL 以及 Redis 才能充分利用其所有功能,例如作业、缓存和 WebSockets。现在,所有这些都可以通过 SQLite 完成,这要归功于三个名为 Solid Cable、Solid Cache 和 Solid Queue 的新的数据库支持适配器。

这些适配器都是基于同一个前提创建的:磁盘的速度已经足够快,以至于我们不再需要 RAM 来完成许多任务。这使我们能够从 SSD 和 NVMe 驱动器比旧的旋转磁盘快几个数量级中获益,从而简化了操作。

Solid Cable

Solid Cable 替代了使用 Redis 作为发布订阅服务器来中继 WebSocket 消息,从应用程序发送到连接到不同进程的客户端的需求。它使用快速轮询,但当通过 SQLite 在同一台服务器上运行时,它几乎与 Redis 一样快。对于大多数应用程序来说,这已经足够快了。此外,Solid Cable 默认情况下会将发送到数据库的消息保留一天,这可能会简化调试棘手的实时更新问题。

Solid Cable 由 Nick Pezza 创建,来自 Working Not Working

Solid Cache

Solid Cache 替代了使用 Redis 或 Memcached 来存储特定 HTML 片段缓存的需求。除了摆脱辅助服务依赖之外,它还允许使用磁盘存储而不是 RAM 存储,从而实现更大更便宜的缓存。这意味着您的缓存可以保留更长时间,并且可以涵盖更多请求,超出第 95 或 99 个百分位数。此外,此缓存可以进行加密,并由明确的保留限制(例如 30 或 60 天)管理。使其更容易满足现代隐私政策和预期。

Solid Cache 在 Basecamp 已投入生产一年多,它存储了 10 TB 的数据,支持 60 天的完整保留窗口,并在引入后将 P95 渲染时间缩短了一半。

Solid Cache 由 Donal McBreen 创建,来自 37signals。

Solid Queue

Solid Queue 不仅替代了对 Redis 的需求,而且还替代了大多数人使用的独立作业运行框架,例如 Resque、Delayed Job 或 Sidekiq。对于高性能安装,它基于 PostgreSQL 9.5 中首次引入的新的 FOR UPDATE SKIP LOCKED 机制,但现在也适用于 MySQL 8.0 及更高版本。对于更简单的需求,它也适用于 SQLite,这使其成为在没有依赖的情况下快速获得第一个 HELLO WORLD,并立即在生产环境中看到您的工作成果的理想选择。

Solid Queue 可以作为 puma 插件运行(这是单服务器安装的默认设置),或者通过使用新的 bin/jobs 命令来启动专用的调度程序。可以运行多个调度程序来处理专用的队列,根据定制的性能调整,所有这些都使用灵活的配置方案,开箱即用无需调整,但如果您需要,则提供所有控制旋钮。

它几乎具备您希望从现代作业排队系统中获得的所有功能。包括健壮的并发控制、故障重试和警报、定期作业调度等等。在 HEY 中,它取代了至少 6 个不同的 Resque gem,成为一个集成的解决方案。

Solid Queue 在过去 18 个月中,在实际生产环境的压力下经过了精心开发,如今它每天为 37signals 的 HEY 运行 2000 万个作业。

Solid Queue 由 Rosa Gutiérrez 创建,来自 37signals。

准备 SQLite 投入生产

除了使 SQLite 能够为 Action Cable、Rails.cache 和 Active Job 提供动力的三个 Solid 适配器之外,还投入了大量工作,使 SQLite 适配器和 Ruby 驱动程序适合在 Rails 8 中用于实际生产环境。

在 37signals,我们正在构建一个不断增长的应用程序套件,它们在生产环境中使用 SQLite,包括 ONCE。现在,CampfireWritebook 的安装量已经达到数千次,它们都在运行 SQLite。这意味着要确保 Rails(和 Ruby)与这个神奇的基于文件的数据库一样好地工作,这对我们提出了很多现实世界的压力。通过使用 WAL 和 IMMEDIATE 模式等正确的默认值。特别感谢 Stephen Margheim 对 一系列此类改进 做出的贡献,以及 Mike Dalessio 对 Ruby 驱动程序中最后一个 SQLite 文件损坏问题 的解决。

用 Propshaft 替换 Sprockets

但 Rails 8 不仅仅是关于更好的部署故事和数据库支持的适配器。我们还将 Propshaft 作为新的默认资产管道。Propshaft 是专注于将 #NOBUILD 作为 Rails 7 中的默认路径(并将更复杂的 JavaScript 设置卸载到 bun/esbuild/vite/等)的使命的红利。作为 新的资产管道,它取代了旧的 Sprockets 系统,该系统可以追溯到 2009 年。那是一个 JavaScript 编译器和构建管道尚未存在的时代。在很久很久以前,我们还无法想象具有出色 JavaScript 实现的浏览器、导入地图以及由于 HTTP/2 而不再受到许多小文件的影响。

这是一个很好的例子,说明有时需要重新从头开始考虑熟悉的问题。事实证明,在我们新的 #NOBUILD 世界中,资产管道只需要做两件主要的事情:提供资产的加载路径并为它们加上摘要以允许远期到期。基本上就是这样。Sprockets 做了比这多得多的工作,其中很多工作的方式早已不受欢迎,并且处于维修不良的状态,很少有贡献者愿意或能够帮助解决它。

因此,我们感谢 Sprockets 15 年的服务,但 Rails 中资产管道的未来被称为 Propshaft。现在,它已成为所有 Rails 8 应用程序的默认设置,尽管我们仍将继续支持现有应用程序的 Sprockets。

Propshaft 由 37signals 的 David Heinemeier Hansson 和 FestaLab 的 Breno Gazzola 创作。

生成身份验证基本内容

最后,简化生产过程也意味着我们应该简化安全性。Rails 很早就开始为出色身份验证系统的关键组件组装高级抽象,以实现这种简便性。我们从 Rails 5 开始就有了 has_secure_password,但最近还在 Rails 7.1 中引入了 generates_token_for :password_reset 以及 authenticate_by。现在,使用 Rails 8,我们将所有这些部分整合到一个完整的身份验证系统生成器中,它为基于会话的、可重置密码的、可跟踪元数据的身份验证系统创建了一个极好的起点。

只需运行 bin/rails generate authentication,您将获得 SessionUser 的基本模型,以及一个 PasswordsMailerSessionsController 和一个 Authentication 关注点。您只需要提供一个用户注册流程(因为这些流程通常是每个应用程序独有的)。无需担心使用这些提供的基础知识自行滚动身份验证设置(或者,天哪,为此向供应商付费!)。

以及其他所有内容

Rails 8 在 Rails 7.2 发布后仅仅几个月就发布了,但除了上面介绍的所有这些令人难以置信的新工具之外,它还包含大量修复和改进。Rails 在所有方面都比我们目前所做的一切都更加努力。这是一个参与框架的绝佳时机,也是第一次登上我们列车的绝佳时机。无论您是喜欢 #NOBUILD 还是 #NOPAAS,或者只是被压缩复杂性的总体使命吸引,您都会在一个充满激情的建设者社区中找到自己的位置,他们像重视生产力一样重视优美的代码。