📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

Rails World 2025 Opening Keynote - David Heinemeier Hansson

Ruby on Rails1:03:55

Transcription

我觉得我应该以一种积极的方式开始。比如,“是的,我们来到了阿姆斯特丹。这里太棒了。”但你知道吗?我不会这么做。我打算一开始就稍微抱怨一下,因为我们这个行业里存在的这种奇特的悖论,我一直感到非常惊讶。

从很多方面来说,现在是成为一名软件开发者的最佳时机。有无数的免费、开源资源可供使用。计算机从未如此快速。一切都应该是美好的。那么,为什么有时事情感觉不那么美好呢?为什么有时我们无法认识到我们本应享受和庆祝的进步呢?事实上,为什么很多时候我们会被事物倒退而不是前进而感到沮丧?

我认为原因之一是我们已经忘记或推迟了弄清楚我们实际要解决的问题是什么。我们将许多大问题分解成微小的问题,然后我们在我们的小孤立区域里处理那个微小的问题,我们可能会取得进展,我们可能会做得更好,但当你把所有的小问题加起来时,我们实际上是倒退了。

这是一个非常奇特的现象,也是我为之奉献了我的职业生涯和我在 Rails 上所做的工作,以期阻止这种现象。不是将问题视为孤立的微小片段,而是思考整个问题,思考整个 Web 开发。正如你今天将看到的,甚至比这还要多。

我在这个行业里待的时间足够长,足以记得我们曾经倒退过的一些事情。当我 1999 年开始工作时,我们使用 PHP 和 HTML 在一个 CVS 仓库中编辑我正在开发的 Web 应用程序。你知道吗?不知何故,我们设法交付了很棒的软件,这些软件被许多人在 1999 年的硬件上使用,包括开发端的机器。

如今,似乎一切都需要所有人的参与,才能在任何时候交付任何东西。发生了什么?我们是如何从“大狗”变成“小狗”的?

对我来说,更奇怪的是部署的故事。1999 年,一名开发人员可以在短短五秒钟内将更改部署到他们的 Web 应用程序。我知道,因为我就是这么做的。我会在我的 FTP 管理器中将我的小文件拖放到生产环境中,它会在五秒钟内上线。

今天,这实际上是错误的。它说,2025 年一个 50 人的团队可以在 15 分钟内完成部署。我这几天一直在和人们交谈。没有人能在 15 分钟内完成部署。他们需要 30 分钟,一小时,三小时,八天。

当我们从古代的 FTP 部署方式(五秒钟)倒退到现代世界(需要一个小时)时,有些事情已经严重、疯狂地出了问题。

今天,我们创建 Web 应用程序所需的活动部件和组件的数量也呈爆炸式增长。为了做什么呢?我们是在创建比 1999 年更神奇、更美好的应用程序吗?使用太空时代的科技来完成辉煌的事情?不,我们只是在做我们一直以来都在做的事情。我们从数据库读取数据,然后写入数据库。然后我们格式化输出,插入一些 HTML 表格。哦,是的,我们现在使用 CSS 了。多么了不起的进步。

在这些复杂性和所有这些活动部件中,我们让事情变得更加残酷。我们倒退了。1999 年,拥有三个九的正常运行时间是很常见的。如今,似乎即使有了他们所有的 Kubernetes、所有的 AWS、所有的 DataDog、所有的东西,人们也勉强能做到这一点,我们并没有让事情变得更好。

对此的普遍解释是,我们被复杂性的商人欺骗了。这些狡猾的公司说服我们使用他们复杂的工具和产品,然后不知何故他们就欺骗了我们。我们很聪明,我们通常不会这样做,但他们太狡猾了。他们太聪明了。

我很久以前写过一篇博客文章,说:“你知道吗?我actually 不认为那是问题所在。我确实认为他们是复杂性的商人。我确实认为我之前提到的许多公司都是复杂性的商人。然后他们喜欢卖给你复杂的东西,让世界倒退。但你知道吗?他们之所以能卖出这些东西并发展壮大,唯一的原因就是你不买。

需要有人从复杂性的商人那里购买,复杂性的商人才能赚到任何钱,而他们正在赚很多钱。他们为什么赚这么多钱?这是因为我们有一种心理需求,希望被视为不仅仅是“增删改查”的猴子。我是一名“增删改查”的猴子。我的职业生涯就是“增删改查”。就是从数据库读取数据,创建记录,更新这些记录,偶尔删除它们。本质上这是一份非常简单的工作。利用 Web 来做这份工作是一种很棒的谋生方式。但你知道吗?感觉太简单了。感觉不够“计算机科学”。我必须在这里运用我的计算机科学学位,现在我们需要更多的复杂性。我actually 认为这是根本原因之一。

我们必须重新拥抱,快乐地、自豪地拥抱这只猴子。我们就是那只猴子。当我们这样做,当我们拥抱“增删改查”的简单性时,我们就可以自由地开始端到端地解决问题。当我们端到端地解决问题时,因为我们不把事情搞得太复杂,我们可以从更高的层面思考问题。

现在,这并不意味着要把一切都削减到骨子里,因为那actually 不是端到端的解决问题。Ruby 和 Rails,从一开始就是一个庞大的框架。它试图完成大多数人创建 Web 应用程序所需的一切,以及他们需要的一切。你知道吗?他们需要很多东西。这不是关于极简主义。事实上,在很多方面,这是关于最大主义。这是关于解决我们在创建 Web 应用程序时都遇到的所有令人烦恼的小问题。这需要很多东西。它需要 HTML 模板,它需要数据库访问、路由、发送电子邮件、后台作业以及所有这些东西。

我认为这已经失宠了。而且是那些制造这些框架的人让它失宠的。你每天看到的新框架,没有一个是在尝试做这件事。没有一个是在尝试解决整个问题。即使有,那也是因为他们刚刚完成了 A 轮融资,刚刚启动了一百万个项目。好吧,祝你好运。

但在开源世界里,我认为我们需要回到解决完整的问题,就像 Rails 从一开始就做的那样。思考这个问题的一种方式是罗马帝国。我喜欢思考罗马帝国的鼎盛时期,而不是它的灭亡。Pax Raeliana 就是罗马帝国的鼎盛时期。我们拥有所有这些领域,所有这些省份,它们都运行得相当好。它们运行得相当好的原因在于,它不仅仅基于技术。它不仅仅是一堆框架。它不仅仅是一堆解决方案。它是一种生活哲学。

我发现,这种生活哲学给了我兴趣、动力和雄心,让我继续前进,继续将这个辉煌、和平的帝国进一步向北、向西、向东、向南扩张。我以最辉煌的方式思考它:Libertas, Proprietas, Pietas。

我们有自由去做任何我们想用这个我们共同拥有的框架做的事情。它以一种“omakase”的形式出现,但你可以随意更改它。它只是 Ruby 代码。你可以literally 执行 `bundle open`,看看一切是如何工作的。如果你不喜欢它,你就可以改变它。天哪,你可以 monkey patch `String` 来做一些疯狂的事情。这种可以让你对自己开枪的自由度是惊人的。

我为 Rails 社区使用锋利的工具而自豪,我们不怕我们的公民。Proprietaires,我们对我们所做的工作拥有完全的所有权。没有人会来告诉我们必须这样做。必须那样做。有建议。我偶尔会告诉你,我认为我们的 `specs` 语法丑陋无比,你应该停止使用它。但你知道吗?你可以自由地忽略我,就像你们很多人多年来一直做的那样,你们这些混蛋。

最后,Pietas,责任。我们不仅仅是框架的消费者。我们不仅仅是一些神奇的开源供应商在天上掉下小包裹和礼物的受益者。不,不。你应该为帝国尽一份力。你应该为框架尽一份力。你应该为开源尽一份力。

所以,我将从那里开始。我将从我的部分开始,我正在为帝国做什么,我正在为开源做什么,我们在过去一年里在 37 Signals 做了什么来为大家带来礼物。

我们将以两种方式开始,或者说,我们将开始。

首先,更多。我们将扩大帝国的边界。我们将征服新的领土,新的问题,新的省份。让我们从一点点“更多”开始。“更多”是 Markdown。Markdown 很棒。它是 AI 的新通用语。AI 喜欢 Markdown,而且,出于某种奇怪的原因,它也真的喜欢表情符号。太棒了。让我们让人们更容易在 Rails 中使用 Markdown,生成 Markdown,使其成为一种普遍的期望。

我最近写了很多 Markdown。我一直在为 Linux 冒险写各种手册。所有这些都用 Markdown 写成,使用我们称之为 House 的编辑器。我稍后会谈到。但那是输入部分。我发现我们需要让 AI 更容易地消费我们正在制作的所有东西,而且是以 AI 偏好的格式,而 AI 偏好 Markdown。

这就是 Rails 8.1 中的样子。当你想要做 Markdown 时,你只需要输入 `format.md`。你可以执行 `render Markdown`,然后你可以传递任何对象,我们将尝试通过 duck typing 调用该对象来调用 Markdown。这是一个仍在等待合并的 PR,用于 Writebook。我可能会在会议期间发布这个,这样你就可以下载整个 Writebook,例如 Marchie 的手册或任何其他内容,作为一个单一的 Markdown 文件,它将运行这个确切的代码。

但让我们再往上一点。我们有一个新的文本编辑器将用于 Action Text。它叫做 Lexie,而我们需要它的原因可能不会让那些一直关注 Trix(我们目前 Action Text 中的编辑器)演变的人感到意外。Trix 是我们 37 Signals 多年来一直在运营和使用的项目。没有多少人愿意帮助我们改进它。所以它最终只是我们 37 Signals 其他所有项目的一个后台项目……我们 37 Signals 的所有其他项目的一个后台项目,它没有得到多少关注。

所以,你知道吗?有时你只需要接受何时应该放弃,我们正在放弃 Trix 作为新的默认设置,我们将使 Lexie 成为 Action Text 的新默认编辑器,因此也是 Rails 的新默认编辑器。

它看起来是这样的,你必须眯着眼睛才能看出与 Trix 的区别,因为 Trix 实际上已经充分涵盖了所有基本功能。但我们可以做得比充分更好。

这里有一个例子,对于 Keynote 服务器,这是一个文本编辑器的实时视图,具有实时语法高亮。Ruby 的实时语法高亮,许多不同语言的实时语法高亮。当你将代码插入到你的 Basecamp 或其他使用 Action Text 的应用程序时,这实际上非常有用。

同样重要的是,紧随 Markdown 的公告之后,你可以将 Markdown 直接粘贴到此编辑器中,它会将其转换为富文本,你就可以做到这一点。你也可以导出 Markdown。我们仍在 37 Signals 上进行这项工作。我actually 在录制这个的时候发现了一个 bug,并且我捕获了它。这是我们正在 37 Signals 上开发的一个新应用程序 Fizzy 的截图。我们在 Fizzy 中使用 Lexie 文本编辑器,它非常棒。

但 Lexie 是什么?Lexie 是一个实现或使用 Lexical。Lexical 是 Meta 的优秀团队开发的文本编辑框架。它为 WhatsApp、Instagram 和 Facebook 提供支持,据我估计,每天有 17 亿人使用它。他们有一个专门负责这个的团队。太棒了。让我们将一些工作和一些负担交给那些真正有动力的人。Meta 的人们非常有动力维护 Lexical。Lexical 每天为 Facebook、Messenger、WhatsApp 和 Instagram 上数亿用户提供 Web 文本编辑体验。喜欢它。喜欢进行升级,我们获得所有好处,而其他人则完成工作。或者我称之为性能优化。你好,Erin。

但这个家伙呢?House。去年,我谈到了 House,一个我们一直在 Writebook 中使用的新的 Markdown 文本编辑器。我们尝试在两个新产品中都使用 House。一个是 Fizzy,另一个还没有宣布。在这两个案例中,我们发现大多数人actually 不想要 Markdown。Markdown 是开发者的绝佳工具。它是 AI 的绝佳工具。而且很多人会说,“那个标签是什么来着,你必须按下去才能成为大标题?”

我们为这两个产品切换到了 Lexical。House 可能不会是我们进一步投入的东西。我们将继续使用 Lexical。

另一个很棒的补充,我们在这里添加的越多,就是 Action Job Continuations。这是一种新的组织作业的方式,可以中断和恢复,而不会丢失所有进度。这是我们在 37Signals 搬离云端时发现非常需要的东西,我们是在几年前搬离的。我们迁移到了 Kamal,我们迁移到了一个设置,在那里我们会关闭任何运行旧代码的容器,在 30 秒内。

现在,这 30 秒并不非常兼容。如果你有一个长时间运行的作业,正在执行一项大任务,比如导出你所有的 Basecamp 数据,如果你的账户很大,这可能actually 需要几个小时。能够以分步方式恢复它意味着我们不会浪费工作。这是一种将这些东西分解的绝佳方式,确保所有作业都可以恢复。

它也将在 Rails 8.1 中提供。但这些想法都在帝国的已知边界之内。

我们恰好与另一个帝国接壤,即原生应用程序帝国。你知道吗?他们在那边有点敌对,但我们必须与他们交易。我们不能仅仅封锁边境,假装那里没有原生前沿。我们不能假装你不需要原生应用程序来创建有竞争力的 Web 应用程序。

我们在大约四年前推出 Hey 时,略感惊讶地发现了这一点,而 Apple 不客气地试图扼杀我们。现在,谢天谢地,他们不成功,我也不记仇。我非常非常记仇。我们稍后会回到这一点。但无论是否记仇。我们仍然需要创建原生应用程序,而且我们需要让它们变得越来越好,因为这就是竞争所在。如果你有一个他妈的生意,你不能仅仅放弃,举手投降,抱怨说,“我不想这样做。”我恰好有一个他妈的生意,我希望那个他妈的生意能赚点钱。这需要客户,而客户想要原生应用程序。所以我们忍了,然后做了。

我们从一开始就在构建混合应用程序,Hotwire Native,一切。每个人看到它时问的第一个问题是:“这看起来太棒了。但如果人们在飞机上需要他们的旅行邮件,而他们没有互联网怎么办?他们该怎么办?”

你可以构建一些东西。那是你的问题。不,不是。一切都是我们的问题。如果离线是每个人都需要的东西,我们就应该解决离线问题。所以,这就是我们一直在努力的方向。Turbo Offline 即将推出。我们已经为此努力了一段时间了。这是 Rosa 的工作。我们将解决这个问题。是的。

解决这个问题的绝妙之处在于,在 Turbo 层面上解决它,我们不仅为原生应用程序解决了它,实际上我们为所有 Web 应用程序解决了它,无论它们在哪里使用。它分两步解决。V1,即将推出。它将是“边走边缓存”。如果你访问 Hey 中的一封电子邮件,该电子邮件将被缓存在该设备上,你可以在没有网络连接的情况下返回它。

第二步将是“预缓存”,就像我说的,这样你就可以预先缓存某些页面,比如你的旅行文件夹,而无需你访问 individual 电子邮件。这将会很棒。

现在,Turbo 已集成到 Hotwire Native 中,这是处理 Hotwire 上所有原生事物的全方位框架。我将完全不谈论这一点,因为今天晚些时候,专家 Joe 将在今天的最后一次主题演讲中谈论即将推出的 Hotwire Native 1.3。它将是惊人的。

在原生前沿也将令人惊叹的另一件事是终于解决了推送问题。终于解决了向原生设备发送推送通知以及更多内容。这在去年我暗示它时被称为 Action Notifier。Action Notifier 演变成了 Action Push。今天,我们实际上有 Action Push 的第一部分,即 Action Push Native 部分,因为我们需要非常迅速地解决这个等式,因为我们将在几分钟内注销我们的 AWS 账户。这需要我们停止使用 AWS Pinpoint 发送原生推送通知,并直接切换到使用发送给 Apple 和发送给 Google 的通知。

Action Push Native 为你完成了这项工作,将它 beautifully 地包装起来,将你所有的推送通知简化为这种可爱的语法。你创建一个带有新令牌的新设备,你将在给定的平台上发送它,该平台可以是 Apple 或 Google。然后你可以设计这些或使用这些 Action Push 通知,附加仅在 Apple 设备或 Google 设备上相关的元数据,并将它们交付给设备。你甚至可以做一些事情,比如静默通知,如果你的应用程序依赖于某些类型的更新。这真的很棒。

这是它的配置模式。将有一个新的 `config/push.yml`,你可以在其中为你的 Apple 集成和 Google 集成进行设置。你输入你的密钥,然后就可以开始了。这非常棒。而且我们在生产环境中使用了几周,在我们切换之后,它发送了,我不知道,我只是随便编个数字,已经发送了数百万条通知。它运行得非常好。

等式中的另一部分是 Web Push。当我们不久前推出 Campfire 时,我对 Web Push 感到非常兴奋。Campfire 有一个原生 Web 应用程序。它不是一个你通过应用商店安装的原生应用程序,但它使用了所有最新、最棒的原生技术,包括 Web Push。它运行得相当好。它并不完美。这也是 Action Push 不仅仅是 Action Web Push 的原因之一。原生通知仍然有一些优势。你可以拉回它们,可交付性略有提高。但如果你在本次会议期间使用 Campfire,并且你收到手机上的推送通知,它基本上是通过 Action Web Push 发送的。

所以,这段代码看起来有点像这样。这是来自 Campfire 内部的代码。这是 Campfire 内部的 Action Web Push 代码。我们还没有提取它。它比原生东西更麻烦,也更复杂。你需要做一些 JavaScript 舞蹈来获取正确的密钥和所有东西。我非常希望看到它被提取出来。我本来打算提取它,但你知道吗?我有很多事情要做,因此我将做一些更棒的事情。

相反,与其收取 Campfire 的 2.99 美元,我们将其免费提供。好吧,别鼓掌。别鼓掌,因为免费*。我需要 Action Web Push 被提取出来。你们中的一个人将完成这项工作。这就是交易。这就是为什么你们免费获得它。我们需要这段代码。请去看看。这个 URL 将在主题演讲结束后或不久后激活。我们需要这个,提取它。我希望你们中的一个人能处理这件事。

所以,这就是更多的内容。我们正在向框架中添加更多的内容。这里有很多想法。其中一些已经在 Rails 8.1 中发布。其中一些将在下一版 Rails 中发布。但要拥有一个健康的帝国,你需要更多。你需要更多的领土,更多的征服。你也需要修剪。你需要收缩某些领域。你需要认识到哪里需要更少。因为这是框架开发的阴阳。你不能只是增长、增长、增长而不修剪掉枯死的树枝和愚蠢的代码。我们确实有愚蠢的代码,我们确实有死胡同,我们确实有框架中一些已经发展到我们不再需要它的地方。有时,是因为我们简单地意识到我们错了,有时,是因为底层技术在进步。

多年来,我一直使用 PUMA dev 来运行我们所有的本地开发,这需要一套完整的设置,而且在 Linux 上效果不太好。然后当我开始使用 Linux 时,我说:“这是什么狗屁?”然后我把它拔掉,换成了 localhost 的荣耀。你不需要 Puma dev。你不需要任何进程来运行你的 Rails 本地应用程序。你只需要 localhost。

你只需要 localhost 的原因是,在 2017 年,localhost 是一个安全上下文。如果你在 localhost 上运行,开发时就没有理由运行 SSL 证书。我不知道这个。当我因为 Puma dev 在 Linux 上需要六个步骤来设置,而且所有步骤都很麻烦且令人讨厌,我不想这样做时,我发现了这一点。所以我发现 localhost 实际上可以完成所有这些工作。我们根本不需要它。我们把它拔掉。这就是我们在 37signals 所做的。

这就是我们现在的开发 URL 的样子。它们有显式的端口,起初我以为这有点奇怪。然后我想,不,它一点也不奇怪。端口对应于我机器上运行的一个进程。所以,如果我想运行 Basecamp 3 + Launchpad + Queen Bee,那就是三个不同的进程。它们应该各自运行在自己的端口上。为什么我们不能让它们显式化呢?处理软件的挑战有一半在于问题是什么?是否值得通过一个曲折的解决方案来消除这些端口?不,不值得。你可以把它们写下来。哦,是的,3010。那是 Queen Bee 的端口。所以我们就都用那个。然后,噗。整个关于如何启动多个本地 Rails 应用程序实例的问题就消失了。太棒了。

另一件事是,我们花了几年时间摸索如何使用 Docker。Docker 在很多方面都令人难以置信,但在开发中使用它却是一件非常麻烦的事情。我们花了一段时间才意识到这种麻烦不必存在。我们可以获得 Docker 的最佳优势。Docker 擅长的是当你拥有对系统而言包罗万象的服务时,比如运行 MySQL,并且你需要运行不同版本,因为你的一个应用程序需要 8.0,另一个需要 8.04。能够拥有多个版本真的很好,而如果你本地安装,你就做不到。

这导致了许多人的一个认识,好吧,我们应该在 Docker 中进行所有开发。然后他们遇到了仅仅做这件事的所有多重问题。你不需要选择。我们可以运行本地 Ruby,顺便说一句,现在由一个叫做 Mees 的项目 beautifully 管理,它使得安装不同版本的 Ruby 变得异常容易,并且将所有东西分开。你根本不需要 Docker。但你仍然需要 Docker 来处理你的数据库。

所以,这就是我们所做的。我们简单地共享一组 Docker 数据库,这些数据库是版本化的,这样如果一个应用程序需要 8.0,它就会连接到那个进程。它将尝试在该端口上运行。如果它需要 Redis 的 7.1 版本,它就会这样做。如果另一个项目需要其他东西,它也会这样做。真正解决了我们在开发中使用 Docker 的主要痛点和主要问题,只针对数据库进行了隔离。

对我们来说更具影响力的,甚至更大的痛苦,我差点说成是“分支”,但它actually 感觉像一颗坏牙。该死的系统测试。十年前,我曾站在一个与此类似的舞台上,自豪地宣称系统测试是未来。理论上,系统测试是绝妙的。你可以端到端地测试一切,通过浏览器进行流程,测试你的 HTML,测试你的后端,但它就是他妈的不起作用。它从来没有起作用。它总是脆弱的,总是坏的,总是慢的,而且完全不值得。

达到这个认识比在 Docker 上摸索花费的时间还要长。但去年,我们合并了 Hey 的一个拉取请求。Hey 有很多系统测试,而且运行时间很长,开发人员一直在努力让它们稳定,我们说:“够了。”如果我们就把整个东西从轨道上炸掉呢?这是确保安全的唯一方法,只留下 10 个系统测试作为烟雾测试,只是整个东西是否正常工作。不要用它来深入测试任何东西。我从来没有听说过我们推送到 Hay 生产环境中的任何一个 bug,这个东西会捕捉到。它不值得。

因此,我们将从 Rails 8.1 中撤销关于所有新控制器都应具有系统测试的建议。我们不再生成它们。框架仍然在那里。我认为它对于非常小比例的冒烟测试是有意义的,但对我们来说,它绝对不值得权衡。

我认为这些认识非常重要,那就是你进入一个新的领域,一个新的领土,想着“这将是伟大的”。然后当它不伟大时,你回到小树篱说:“系统测试?不。”

说到测试,你知道当我们离开云端时,什么让我非常恼火吗?就是这个该死的云测试运行器。我有一个小文本,所以我将为你朗读。这是在 BCX 上进行的测试,BaseCamp 的第二个版本。他们仍然运行着一个相对较小的应用程序,比 Hey,比 Base 3 小。运行这些测试花了整整 10 分钟,而且它在八个不同的并行项目中运行。它们都被小心地设置在云端运行器上,花了 10 分钟。总的麻烦,完全太长了。但我没有……你该怎么办?你必须做什么?但如果我们有很多测试。我们必须运行测试。我们不能就这样全部杀死它们。也许我们可以杀死系统测试,但我们不会杀死所有东西。

然后就像,“你知道吗?这在 2019 年是有道理的。我们的 MacBook 里有 Intel 芯片,它们很糟糕。而且它们基本上六年没有改变,因为 Intel 陷入了困境,无法弄清楚如何推出他们的新产品。你拥有所有这些云 CPU,AMD EPYC 表现出色。一切都很棒。开发场景很糟糕。

然后发生了神奇的事情。台积电,通过苹果和其他公司的恩赐,真正改进了我们本地开发机器中的芯片,以至于我们现在拥有的芯片、CPU 比我们在云端租用的东西要好得多,速度也快得多。

这是 Hey 的测试套件。Basecamp 的测试套件,正如我刚才展示的,有 13,000 个断言。Hey 的测试套件有 30,000 个断言。我看到一次云运行 Hey 的测试套件,花了远远超过 15 分钟。你可能读不出来,但你知道今天你能买到的最快的 AMD 的最快速度是多少?一分十二秒。即使在 Apple M4 芯片上,也低于四分钟。即使对于像 Hey 这样相对较大的应用程序,这完全可以在本地运行。而且你们中的许多人拥有比这更小的应用程序。你们中的一些人拥有比这更大的应用程序,而这些东西都不适用于你们。你们无法,抱歉,在本地运行 Shopify 的测试套件。这明天不会发生,但那是制作 Rails 应用程序的 0.001%。你们中的绝大多数人都应该能够复制这些数字,并在本地运行你们的整个测试套件。而且如果你在 Linux 上运行,它的速度大约是 Mac 上的两倍。你在这里拥有 M4 Max,我测试过的最快的 Apple 机器,2 分 22 秒。在其下方,你拥有我信赖的 Framework 笔记本电脑的 2 分 5 秒。然后你拥有 Framework 台式机的 2 分 23 秒。这完全足够快了。你只需要在本地运行它,你就可以消除运行云运行器的所有复杂性。

现在,这里有一个常见的反对意见。好吧,如果我们允许开发人员在自己的机器上运行东西,首先,你会得到,“它在我的机器上运行。”是的。你认为仅仅因为它在云端运行器上运行,就意味着什么吗?这意味着你固定了你的依赖项,你固定了你的版本。这就是我们做其他事情的原因。我们使用相同版本的数据库、Redis、Docker 中的一切,并且我们可以精确地固定它。我们不依赖于 Homebrew 中的随机版本来帮助我们。我们使用 Mees 来精确固定我们将要使用的 Ruby 版本。在这两者之间,Ruby 版本和数据库版本,就是这样。任何你可能发现的不是确切版本的晦涩语言或库,它都不会起作用。我们已经运行这个设置很长一段时间了。我们没有遇到任何问题。如果你遇到了,请权衡一下知道你的 PR 是否准备好部署所带来的喜悦,仅需一分十二秒。

现在,我们确实保护了 PR,因为现在没有云运行器了,它们不能 just 被合并。我们使用 GitHub 的一个很棒的功能,你可以要求通过测试的签名。你可以使用我们提供的工具安装它。当你这样做时,它要求一个人证明他们已经签署了,他们已经运行了测试并且所有测试都通过了。这听起来似乎行不通,因为它似乎依赖于信任。但你知道吗?信任是有效的。在大多数组织中,你的员工不是混蛋。他们actually 是程序员,他们想交付工作的软件,而且他们知道如果他们在这个证明上撒谎,他们就会被解雇。我actually 会说,这是一个非常有效的执行机制。所以不是问题。

在 Rails 8.1 中,我们已经内置了一种方法来在本地完成所有这些工作,不仅仅是测试。有一个全新的 DSL 用于声明你的本地 CI 运行,你可以在其中运行你的 RuboCop,你可以运行你的 `gem audit`,你可以运行你所有的测试,你可以在边缘进行签名以清除 PR 以便合并。当我们本地运行这个时,它几乎不花费任何时间。

让我们换个话题。我进行的关于不同本地计算机运行本地测试速度的所有基准测试,以及我意识到为什么我们要为运行慢速测试支付云提供商的费用,而我们可以用我们已经拥有的机器快速运行它们,这让我想起了这个。这是 Fortnite。Fortnite 每秒必须渲染整个 3D 图形场景 120 次。他们有八毫秒的时间来渲染这个该死的场景。然后你告诉我,在云端通过一些该死的纸面测试需要 15 分钟?不,这不合理。

当我想到这一点时,我想,“你知道吗?有很多事情真的不合理。我们等待的事情太多了,而且等待的时间太长了。”我一开始举的例子是一个很好的说明,FTP。我们可以五秒钟内完成部署。现在我们有信心或满足于在 15 分钟、半小时、三小时、八天内完成部署。不,不,不。我们将解决所有这些问题。我们将应用工程原理,我们将为一切设定一个框架预算。我将从这里开始,我们将有一个启动预算。

一个新开发人员加入一家新公司应该花几个小时设置他们的该死笔记本电脑的想法是荒谬的。在 37signals,这是我们的启动预算。在 15 分钟内,你应该能够从一台什么都没有的全新机器,到一切都设置好,并且更改已部署到生产环境。这就是我们的预算。

为了实现这个预算,我听了 Allan K. Isch 的话。真正认真对待软件的人应该自己制作操作系统。让我们这样做吧。让我们自己制作操作系统。让我们现在就做。让我们看看我们是否能在预算内完成。我们有五分钟时间从这个小 USB 密钥上在一台全新的 Framework 台式机上设置 Amachi。这是秒表。我们开始吧。

我将插入 USB 密钥。我可以把它插进去。我将打开机器并启动秒表。我们开始吧。

现在我们将在一台全新的 Framework 台式机上安装 Lomachi,如我所说。我们不会保留任何东西。我们将清除一切。这是一个我花了,我差点说两个月,但不是,是过去两个月痴迷的项目。让我的生活完全被一个 Linux 神占据,因为我深入研究了不应该花几个小时来设置新机器的想法。而且,我也不必向苹果请求任何权限。

所以,我们将设置这台机器。我将输入我的用户名。我将给它一个快速的密码。我不需要输入名称或电子邮件地址,主机名。我们就叫 Amachi。我们在阿姆斯特丹。这是真的。一切看起来都不错。我们将把它安装在内部 NVMe 驱动器上。是的,我们将清除它。我们开始吧。

当它安装时,让我告诉你一些关于 Amachi 的事情。我大约在 18 个月前切换到了 Linux,我做了其他人切换到 Linux 时所做的事情,我使用了 Ubuntu。这是最流行的 Linux 发行版。它真的很不错。Canonical 在整合一个 Linux 发行版方面做得很好,它不会对 Mac 用户来说太陌生或太吓人。这正是我当时所需要的。一些似曾相识的东西,但建立在 Linux 的基础之上。我花了一年时间愉快地调整和改变事情。

然后我看到一个 YouTube 视频。制作它的人,那个混蛋,把我拖入了 Linux、Ricing 和 Tiling 窗口管理器,特别是 Hyprland 的神秘世界。我发现自己像是掉进了兔子洞。这是什么地方?什么意思,我不再用鼠标移动窗口了?什么意思,当我打开东西时,它们都会自动调整大小?为什么它看起来这么好?为什么它看起来这么神奇?为什么一切都是两步的?一个终端用户界面?那不是我们 80 年代放弃的东西吗?

然后我想,哦,80 年代。我喜欢 80 年代。我记得 80 年代。它们很酷。我记得 90 年代,当时我在 Amiga 上运行一个 BBS,我们有很酷的 ASCII 图形。哦,就像那样。就像 90 年代。我记得 BBS。它们真的很有趣。如果电脑再次变得有趣会怎么样?那不是很棒吗?是的,那会很棒。电脑应该有趣。它们应该酷。它们应该看起来有点像黑客电影。那actually 是一种值得追求的美学。

如果我们能按照那个形象,按照那种酷炫的氛围,那种酷炫的美学来构建一个完整的操作系统呢?哦,而且,建立在他妈的 Linux 上,这个驱动着世界上 95% 服务器的操作系统,这个驱动着 Web 的系统。这个系统在过去的 34 年里被一个芬兰的、脏话连篇的人优化了。是的,这actually 是我想运行的系统。那个人很痴迷。而这种痴迷产生了有史以来最伟大、最大的开源项目。Linux 真是太棒了。我花了 30 年时间在服务器上学习 Linux,我完全忽略了你actually 可以在你的电脑上运行它,而且它已经变得非常棒了。

现在,我知道你们中的许多人曾经尝试过某个版本的 Linux,而且你们的 Wi-Fi 无法工作,或者你们的打印机无法打印,或者在过去的 30 年里尝试过 Linux 的任何人的任何其他轶事都会有一堆鸡蛋。你知道吗?首先,我要说。几乎所有这些问题都已解决。你知道吗?这就是如果你持续解决一个问题 34 年会发生什么。最终会变得非常好,如果你如此痴迷的话。

我们已经看到了 Ruby。当我开始使用 Ruby 时,它是 1.68 版本。你知道今天的 Ruby 有多快,多好,功能多多少吗?当然。哦,该死,我们完成了?你在开玩笑吗?这甚至不到五分钟。这是四分四十四秒。然后我只需要拔掉这个东西。哇。这相当快。

如果痴迷的人继续努力,事情就会变得很好,特别是开源,特别是如果你能聚集一群和你一样对让技术变得更好感兴趣的人。这就是为什么在所有我们关心的 Web 开发领域,开源都在获胜。你还购买编辑器吗?你购买数据库吗?你购买 Web 框架吗?不,你不买。你使用开源的,如果它们不符合你的要求,你就可以自己去改变它们。这不是很神奇吗?

哦,这是 Amachi。你好。让我们创建一个 Rails 应用。因为当然,它包含了在启动这个东西的最初五分钟内创建 Rails 应用所需的一切。所以,我们将进入这里,我们将执行 `Rails new blog`。当然,它将是一个博客。不是 15 分钟的博客,而是五秒钟的博客。

当我们开始这个时,我们也意识到,你知道吗?这仍然是一个正在进行中的工作。如果你在低分辨率屏幕上运行它,你将不得不进入一个配置文件并稍微更改一下。但这重要吗?你害怕一点点配置吗?不,你并不害怕一点点配置。当你看到 NeoVim 弹出时,你会感到兴奋,比如,“哦,所有酷孩子都用那个。”我也可以吗?是的,你可以。它是免费的。

所以,我们将这样做。我们现在有了我们的 Rails 应用程序,一个博客。我们将生成 R,因为当然,它内置了我喜欢的别名,只是 R,不是 `rails`,不是 `bin/rails`,只是 R。R,生成 `scaffold post title:string`。我们已经完成了。然后我们需要迁移数据库。然后我们需要在 `dev` 上启动它。

当我们这样做时,我们可以跳到这里。哦,你好,Rails。你好,Rails。你好,Rails。你好,Rails。哦,这不是很棒吗?这是一个不错的错误屏幕。这就是真正的东西。一个全新的操作系统,大约六分半钟的“Hello World”。而且不仅仅是“Hello World”,而是他妈的酷炫的“Hello World”,可以变成绿色。怎么样?比如,哇,看看那些窗口。如果到处都看起来很酷怎么办?如果你有一个像 90 年代一样的屏幕保护程序怎么办?那不是很神奇吗?

这就是 Amachi。我过去两个月一直在致力于此。我将把它打造成在上面开发 Ruby on Rails 的最佳方式,我希望你能试试。即使你喜欢你的 Mac,也去看看。我们实际上有 200 个带有 Amachi 的 USB 密钥在 37 Signals 的 Base Camp 3 展位上。如果你真的想安装它。在你拿到那个密钥之前,它花费了我 7 美元。所以我会直视你的眼睛说:“你真的会安装它吗?我不是给你一个纪念品。”所以这是给那些真正想安装它的人的,来找我们。

所以,让我们回到演示文稿。这是我的备用幻灯片,以防现场演示失败。它没有失败,所以我们不需要它们。这不是很棒吗?我喜欢事情顺利进行。

制作你自己的操作系统的好处是,你可以放入所有你想要的东西。我给你举一个简单的例子。Amachi 预装了 Git,预装了 Mees,预装了 Docker,预装了数据库,预装了 Web 开发人员想要的一切。让我们深入研究一个 Git 的例子。它预装了 LazyGit,这是一个用于管理 Git 交互的绝佳 TUI。这在 NeoVim 中运行,我以前使用 GitHub 桌面应用程序。不错的应用程序,不是 TUI。这要好得多,快得多。我简直不敢相信这个项目已经存在多年而我却没有使用它。

我们设置了常见的别名,比如你看到的 R。我们可以为所有 Git 操作设置常见的别名。我们甚至可以预先配置你的用户名和电子邮件地址。你的提交将立即生效。我们从注册表中提取这些信息。我们可以做所有事情。我们可以设置这些别名。正如我所说,我们可以有一个很棒的 Starship 提示,它会告诉你仓库中是否有新文件,并且是脏的,需要检查。我们可以做所有事情。我们可以做所有事情,因为它是我们的,而且我们不必乞求苹果一点点。不,我们可以得到一个像你头一样大的面包。

然后我们可以意识到我们不必止步于此。在创建 Amachi 之后,我意识到,实际上,为什么整个新机器的设置不是 37 秒完全一样?它应该是。所以我们创建了一个定制脚本,可以在几分钟内安装所有东西,检出所有东西,开发人员就可以准备使用了。正如我所说,在这个预算内,我们希望在三分钟内完成部署。这听起来对很多人来说很疯狂,他们可能花费了几个小时,甚至几天。但这是一个 Fizzy 的部署,我们正在开发的新项目。你可以在角落里看到它,58 秒。我们可以让它更快,运行本地 CI,部署一切。

虽然我会说这是 Base Camp 4。更多的服务器。大约需要四分钟。我知道,可怜的小狗。我对此也感到有点羞愧。我们将把那一分钟削减掉,降到三分钟。我保证。我们将回到这一点。我们将回到一种开发方式,感觉更像 99 年,感觉没有不必要的复杂性,我们将移动得更快。

当我们部署东西时……只是一个小插曲。我真的很喜欢这些迷你 PC。这些盒子里的性能真是令人惊叹。这些堆栈有 76 个核心,我认为有 300 GB 的 RAM。这很酷。我拿了一个盒子,你知道你们这周一直在使用的 Campfire 吗?是的。

它运行在我的壁橱里。字面意义上,就是在那该死的机器上。那不是一张库存照片。那是我,在我脏兮兮的杂物间里,拍下那台为在座各位运行 campfire 的机器的照片,它几乎没怎么费力。哦,而且它才 300 块钱。你知道如果我在云端运行它,那得花多少钱吗?哦,这里有个水滴。哦,该死。那种性能水平,一个月得花 300 块钱。我知道这真的很糟糕,这只是开玩笑。我知道它们就在那里。你好,Roku。这种性能水平一个月要花费 1200 多块钱,而我的壁橱里只需要 300 块钱就能运行。你知道吗?你可以直接做事情。这给了我一个想法。想法是,如果这种性能水平对普通人来说只需要几百块钱就能获得,那么在企业层面我们可以做什么呢?我们多年来一直在运行两个主要的数据中心,为 37 Singles 服务,我们刚刚在阿姆斯特丹建立了一个外围节点。实际上就在阿姆斯特丹,就在这里。我们这里有一些 hay 服务器。所以如果你在阿姆斯特丹使用 hay,它会非常非常快。但如果我们做得更进一步呢?如果我们不拥有这些大型数据中心,而是拥有微型数据中心呢?如果它看起来更像我的杂物间,而不是这个巨大的东西呢?所以,正如我之前说过的几次,我们正在开发一款名为 Fizzy 的新产品。每当我开发一款新产品时,我都想挑战极限。有时这与产品的好处非常契合。其他时候,这只是纯粹的乐趣。我想要挑战的极限之一是互联网的概念。互联网就像包裹在全球各地飞来飞去,而且速度非常快,因为你知道吗?光纤上的包裹,它们以光速飞行。一点点光在这些玻璃电缆中反弹,速度约为每秒 3 亿米。嗯,这是什么计算?我是在四天前做的这个计算。计算的目的是,哦,地球的周长。地球的周长是 4000 万米。如果你将这两者相除,就能得到光绕地球一周的理论时间。是 137 毫秒。而这应该是包裹在全球各地运输的理论极限。嗯,这需要一点时间,因为并非所有电缆都绕地球直线延伸,也并非所有光线都沿直线传播。它实际上在这些电缆中反弹。所以当你实际测量时,从一台计算机到另一台计算机,大约需要这么长时间。纽约到洛杉矶的 RTT 是 70 毫秒。如果你从纽约到悉尼,发送一个包裹并收到回复需要 220 毫秒。这花费了大量时间。你们可能一直在查看你们的性能图表,了解你们的 X 运行时间有多长。220 毫秒,对很多人来说,这就是他们的预算,而你却在一个该死的包裹上就花光了。而且你不能只发送一个包裹。当你发出一个 POST 请求,而且是第一个请求时,首先你需要做一个 TLS 握手。哦,好吧,那是一个包裹。而且这已经是高度优化的了。以前需要两三个包裹。现在我们把它减少到一个包裹,但仍然需要 220 毫秒。你向它发送一个 POST 请求,然后收到一个包含浏览器下一步应该去的位置的响应。哦,220 毫秒。你再发一个 GET 请求去那个位置,220 毫秒。从纽约到悉尼的一个 POST 请求,仅仅因为光的延迟就花费了将近 700 毫秒。如果你在其他地方进行这个实验,如果你在纽约到洛杉矶进行,它仍然非常重要,因为这些距离很远。美国实际上是一个相当大的国家。纽约和洛杉矶之间来回的光延迟就有大约 210 毫秒。但我还做了一些其他测试。如果我们把东西放得近一点呢?我现在在哥本哈根。当我 ping 我本地的哥本哈根网站时,它就在街对面,只需要两毫秒。这相当快。即使我走遍全国,也只需要八毫秒。当我到达 Falconstein,赫兹纳在那里有一个数据中心,在德国,需要 17 毫秒。当我到达这里时,需要 25 毫秒。这实际上不算太糟。当我们把这些加起来,所有这些连接上的光延迟要少得多。纽约到悉尼的 660 毫秒,现在是 6 毫秒。如果我能一直待在哥本哈根,那将是一个巨大的速度提升。现在,如果你在这里做一个完整的实际请求,你说你的服务器上一个 POST 的额外运行时间是 150 毫秒,你得到 75 毫秒,整个操作,从发起新的 POST,纽约到悉尼,将近一秒钟。哥本哈根到哥本哈根,200 毫秒,多一点点。你知道还有什么大约是 200 毫秒吗?一级方程式赛车手在所有灯熄灭时的反应时间。这就是我们应该瞄准的目标。这就是我们的目标,我们不应超过一级方程式赛车手的响应时间。我们该怎么做?我们追逐着云产业十多年来一直在追逐的白兔。边缘计算。我今天早上看到一个有趣的推文,来自 @a_level,他说,边缘计算全是胡说八道,没人能让它奏效。你知道吗?我倾向于同意,但听起来也像一个有趣的挑战。如果其他人都没能解决,那我们来解决。我们打算通过 Fizzie 来解决这个问题,采用许多小型外围节点的模式。本质上,壁橱里的服务器便宜得要命,我们不能有很多这样的服务器吗?是的,我们可以。但我们首先需要做的是确保我们建立的每个数据中心都不需要我们为每个客户所需的整个庞大的数据库,并且运行那个 BaseCamber。嘿,这就是它昂贵的原因。实际上是数据,而不是计算。因为一旦你开始细分你的用户,你在那个区域对计算的需求就会减少,但你仍然需要整个数据库。不,我们需要的不是这样,而是让每个数据库存储一切,所有数据,但只提供一部分查询。如果我们能做到这一点,如果我们能实现这一点,我们就可以在各地拥有迷你数据中心。我们可以到处都有这些小节点,如果我们不需要所有那些复杂的基础设施。对于 Fizzy,我们也许可以在这里到处都有。如果我们把 Fizzy 放在我列出的所有这些城市,几乎所有的客户都会在 25 毫秒内到达一个外围节点,他们的响应时间会感觉快得多。为了实现这一点,我们已经竭尽全力。我们移动的第一块“地球”是一个名为 Active Record Teneting 的项目,因为要让整个设置正常工作,我们需要打破所有人的单一构建数据库,并将其变成每个客户一个数据库,这样我们就可以将数据库放在客户旁边,或者尽可能靠近客户。这需要我们在 Active Record 和其他数百万个框架的内部进行大量的挖掘。Mike 一直在致力于此。我们将把它推出。已经有一些更新已经解决,但基本思想是创建租户,租户是一个数据库对一个客户,并能够将所有内容流经它。这不仅对性能有好处,对隔离、备份、隐私以及其他无数原因也有好处,而且现在你可以将这些数据库放置在世界各地。但是当你这样做并将所有这些数据库放置在世界各地时,你需要同步它们。这是困难的部分。为了做到这一点,我们启动了另一个项目,Kevin 一直在致力于此,我们将在今天的晚些时候讨论,那就是 Beamer。Beamer 是一种复制 SQL 类数据库的简单方法,这就是我们为这个项目使用的。你也可以使用 MySQL,但我认为 SQLite 非常适合每个客户都应该拥有自己的数据库这个想法。这个设置保持了它的复制。如果这听起来有点像 LiteFS,那是因为它就是,但它是为完全不同的规模而构建的。它是为每个客户数万个独立数据库而构建的。它是为每秒数万次事务而构建的,因为我们不仅仅是复制一个、两个或一百个数据库,我们是为每个客户复制一个。最后,我们需要一种方法来路由所有这些东西到互联网上,以便人们能够连接到离他们近的外围节点。我们扩展了 Kamal proxy,添加了这个地理组件,这样我们就可以得到一个看起来像这样的设置,你可能在美国有数据库,也可能在欧洲有数据库。如果你正在访问一个在美国的客户,进行 GET 请求,你可以根据地理路由被路由到哥本哈根的应用程序服务器和美国东部的应用程序服务器。这些都是读取器。读取器可以从任何地方安全访问,但我们仍然有一个主写入器。这是棘手的问题。我们还没有解决所有分布式写入器的问题。但是当你这样做时,你会被重定向到写入器。为了实现这一切,我们需要回到那个神奇的 1999 年,那时每个人都知道一切,并且以完美的远见为整个互联网设计了一切。这是来自 RFC 2616,它定义了 HTTP 1.1 协议。它告诉我们什么?它告诉我们,GET 和 HEAD 方法不应该有除了检索之外的任何意义。这是一个非常冗长的说法,意思是:当你进行 GET 请求时,不要他妈的写入,这会毁掉一切。所以我们将把所有写入限制在 POST 请求和其他方法上,我们搭乘 POST 的便车。当你这样做时,你就能获得 1999 年的智慧。从现在开始,你可以让这一切都正常工作。最后,我们当然使用会话亲和性,因为如果你向写入器写入数据,你可能会得到一个陈旧的读取。如果你被发送到一个尚未更新的读取器,标准的做法是随便猜一下,说,我想在一秒钟内,大概就可以了。这是一种非常糟糕的做法,因为它意味着当你写下评论时,你经常会被重定向到那个评论的写入器上,而那个写入器可能离你很远。你想尽快被重定向到读取器,一旦读取器准备好。如果你运行一个非常快的复制,并且你拥有这种技术,你就可以做到。所以,我们不再只是取一个静态的数字一秒钟,而是将其提炼成一个事务 ID。如果那个事务 ID,我们已经写入数据库的内容,在读取器上可用,那么我们就没问题了。如果不行,读取器会知道这一点,我们将返回一个标头,将你重定向到其他地方。好了,这就是我们的礼物交换。它充满了更多内容。它是 Action Job Continuations in Rails 8.1。它是 Action Native Push,目前处于 Beta 阶段。它是 Turbo Offline,很快就会发布。它是 Hotwire Native 1.3。去看看今天的晚些时候的开幕演讲。它是 Action Text Lexy,今天在 Beta 版中发布。它是 Active Record Teneting,我们还需要完成它,Beamer 和 Kamal GeoProxy 也是如此。它是 Less,就是你可以直接运行原生 Ruby 和 Docker DBs 的想法。就是你可以使用 localhost 进行所有开发的事实。就是我们不再需要系统测试,我们可以在本地运行我们的测试,我们可以进行脚本设置,我们可以在 15 分钟内准备好一台新电脑,我们可以从本地部署。这有很多东西。其中一些好东西正在 Rails 8 中发布。现在,开幕演讲结束后,那是 Raphael。他是发布经理。他将把它推出。我邀请你看看 Omachi,看看 Linux,更新你可能相当古老的关于 Linux 是什么、如何工作或它可能是什么样子的想法。我邀请我们所有人进行更多的端到端问题解决,进行更多的端到端开源,不要接受我们的堆栈中有某些部分,无论是计算、服务器还是框架,如果我们想改变它们,我们就不能改变它们。我们应该能够改变一切。我们应该拥有一切,因为我们想要端到端的自由。我们不希望别人告诉我们该做什么。我不想让别人告诉我该做什么。我当然不想让苹果告诉我该做什么,或者我能做什么,或者我不能分发什么。去他妈的苹果。休息前,我们将在 11:15 回来。我想要自由,我想要所有权,我想要责任。我想要自由、所有权和责任。而你如何运用这些美德呢?嗯,这取决于你,不是吗?非常感谢。