我在Slack论坛、Hacker News的评论区,以及晚上的Discord聊天中,多次看到这样一种观点:

“我就想要类似Heroku这样的服务。”

我自己也说过这句话。不过我当时并没有完全理解自己所说的含义。

说Heroku很好,并没有错。它确实非常出色,而且开发它的团队领悟了一些目前大多数基础设施公司还未能真正掌握的理念。

但是当Salesforce在2022年取消了免费套餐(最近又宣布不再向新企业客户提供免费服务)时,人们开始匆忙进行系统迁移。这时出现了一个有趣的现象:几乎所有人都误解了问题的关键所在。

他们认为人们喜欢Heroku的原因在于它的部署流程非常简单方便,于是便努力开发出更加易于使用的部署工具。

但事实并非如此。

Heroku究竟提供了什么

大约在2019年左右,当我使用Heroku开展一个副项目时,我完全没有考虑过基础设施方面的问题。我把代码推送到Git仓库,系统就会自动完成部署;Postgres数据库也会自动配置好。如果需要添加队列处理功能,我就添加相应的插件而已。所有这些操作都遵循着同一个思维模式,在正常的工作日里,这种思维模式几乎不会占用我任何注意力。

Heroku真正提供的并不是一个简单的部署流程,而是一种让人无需考虑基础设施细节的体验。

这个区别其实比听起来更重要。因为一旦你开始思考基础设施相关的问题,哪怕只是稍微思考一下,这些问题就会影响到你的整个工作过程。

你会因为担心部署的复杂性而做出错误的决策;会因为不清楚各个组件之间的连接方式而推迟产品的发布;甚至会把原本可以吸引新客户的功能开发工作搁置一旁,而去解决那些与基础设施相关的问题。

Heroku消除了所有这些麻烦。它提供了一个统一的平台,所有的配置都已经预先设置好,只需支付一笔费用,遇到问题时也可以在一个地方找到解决方案。

其他替代方案虽然做对了一件事,但却忽略了其他关键点

在Heroku的免费套餐取消后,Render、Railway和Fly.io等平台应运而生。这些工具确实比自己手动管理EC2更加方便。我曾经使用过它们中的几种,也无意中对任何一家平台不公。

但是实际上,当你使用这些替代方案时,会遇到以下问题:

你首先需要将应用程序部署到Render平台上,然后在那里配置Postgres数据库,并将连接信息设置到环境变量中。

接着如果你发现需要后台任务处理功能,就需要注册Upstash服务或添加Redis实例;如果需要对象存储空间,就必须在AWS上创建S3 bucket,因为Render平台并不提供这些功能。

这样一来,你就需要管理三个不同的控制面板、三份不同的账单信息、三组网络配置规则,同时还得协调这三个供应商提供的服务,并通过环境变量来确保一切正常运行。

Railway更接近于最初的设想,其各组件之间的集成程度也更高。但实际上,它仍然是运行在AWS平台之上的。你支付的费用包括了Railway的利润以及亚马逊的利润,这意味着你需要为这种服务模式支付两次费用:一次是给亚马逊,用于支付实际的计算资源使用费用;另一次是给Railway,因为你可以不用直接与亚马逊打交道,从而节省了一些手续成本。

Fly.io采取了最为大胆的做法:他们选择使用裸机硬件,完全不依赖AWS平台。这种架构设计从根本上解决了双重利润抽取的问题。然而,这种集成方式仍然存在一些缺陷——在Fly.io平台上使用的Postgres数据库仍需要用户自行进行配置连接。那种“所有服务都能无缝连接”的体验,在Heroku平台上确实存在,但在Fly.io平台上却无法实现。用户仍然需要自己负责处理各种连接细节。

没人会谈论的问题:不同服务之间的数据传输费用

有这样一个问题,我花了好长时间才真正理解它背后的含义。

当你的应用程序、数据库和存储服务分别由不同的供应商提供,或者甚至属于同一云服务提供商的不同服务时,它们之间进行数据传输就会产生费用。通常这种费用并不高,但一旦使用频率增加,费用也会迅速上升。

例如,如果一个应用程序每天需要从数据库中读取10,000条数据,对处理结果进行计算,然后再将数据写入S3存储桶,那么它实际上需要在三个不同的方向上进行数据传输。在依赖大型云服务提供商的平台上,其中一些数据传输操作会跨越不同的计费区间。

但如果这些应用程序、数据库、存储服务和队列系统都运行在同一套裸机硬件网络上,那么这些数据传输操作就是免费的——因为数据根本不会离开这个网络范围。

这不是一个假设性的问题,而是这两种平台在架构设计上的本质区别。这种差异会随着时间的推移逐渐累积起来,但在任何一张单独的账单上都无法清晰地体现出来。

“坚持己见”是在做实质性的工作,而不是在做营销

我曾经遇到过一些团队,他们花费了大量的工程时间来讨论应该使用哪种队列系统。其实他们并没有真正去实施这些选择,只是在反复争论而已——SQS、BullMQ、RabbitMQ,还是三年前在某篇博客上读到的某个方案……

支持“坚持己见”的平台设计,并不是因为你觉得自己无法做出这个决定,而是因为这个决定其实并没有你想象中那么重要。你把时间花在讨论这些选择上,实际上就是在浪费那些本应用于提升产品竞争力的时间。

对于几乎所有的初创企业来说,Postgres都是一个合适的数据库选择;与S3兼容的存储方案也能满足绝大多数文件存储需求;而一个可靠的队列系统自然也是必不可少的。但这些选择其实并不复杂,十年前就已经不再有什么争议了。真正值得关注的是你的产品本身。

一个“坚持己见”的平台会迫使你停止对那些已经确定下来的问题进行无休止的争论。这并不是一个限制,恰恰正是这种设计理念的目的所在。

关于“锁定效应”的问题,让我们坦诚地回答它

每当有人考虑使用一个垂直整合的平台时,我最常听到的质疑就是:“如果我想离开这个平台该怎么办?”

这是一个合理的问题,我以前也经常问自己这个问题。我现在明白了:所谓的“锁定效应”几乎总是理论上的问题,而且通常是由那些从未真正尝试过更换平台的人提出来的。

真正的“锁定效应”意味着你的代码依赖于某些专有的技术或工具。比如只能与某个特定供应商合作的定制SDK,其他地方都没有的查询语言,或者需要重新编写代码才能迁移的应用程序部署模型。

如果你的应用程序运行在容器中,使用标准的Postgres连接字符串,通过AWS SDK与S3进行交互,并且通过标准协议将任务发送到队列中,那么你并没有被“锁定”在任何特定的平台上。你只是把应用程序部署到了某个地方而已。迁移的过程其实很简单:只需要使用`pg_dump`备份数据,然后将备份文件复制到新的存储空间中,最后再通过`docker push`将应用程序部署到新的环境中。我曾经在一个周末就完成了这样的迁移操作。

那些真正会导致“锁定效应”的平台,往往是那些将所有功能都封装在自己专有的技术层中的平台。比如具有自定义运行时环境的无服务器函数,拥有专有查询功能的供应商特定数据库,以及只能在某个特定网络环境中使用的边缘计算服务。这些才是真正值得我们警惕的地方。

各种替代方案的缺陷所在

“Render”平台是最容易推荐、也最容易随着业务发展而不再需要的解决方案。只需部署一个Next.js应用程序,然后使用托管版的Postgres数据库,就可以了。

但问题会在第三个月左右出现:当你需要后台任务和对象存储服务时,“Render”平台本身并不提供这些功能。

于是你不得不使用Upstash来处理队列任务,使用AWS S3来存储数据。这样一来,你就会面临三个不同的管理界面、三份独立的账单,以及三个需要相互信任的网络环境。部署过程可能只需要几分钟,但随之而来的各种配置和调整工作却会耗费整个下午的时间。

“Railway”平台看起来比“Render”更加集成,其开发体验也确实不错。但它运行在AWS平台上。这并不是对开发团队的批评,而是一个具有潜在影响的结构性问题。正如我之前所说,你在使用“Railway”的同时,也在支付亚马逊的利润;而且如果“Railway”的配置方式不合理,你的应用程序与数据库之间的数据传输可能会跨越不同的账单结算范围。虽然单张发票上看不出来成本有多高,但长期下来这些费用会累积起来。

“Fly.io”在架构设计上做出了非常有趣的尝试:它使用真实的硬件设备进行运行,而不是依赖于任何超大规模云计算服务,因此有效地避免了双重利润抽取的问题。

我曾经在“Fly.io”平台上进行过部署,发现其在边缘计算方面的性能确实很出色。不过计算资源和Postgres数据库仍然是分开管理的,存储也需要通过外部接口进行连接。“一切都被紧密集成在一起”的感觉并不存在,因为这些连接仍然需要你自己去配置。

那些“只是想要类似Heroku这样的平台”的人们真正需要的东西

我对此思考了很多,我认为这种对Heroku的怀念情绪确实是存在的,但这种怀念其实把方向搞错了。

人们并不是特别想要Heroku本身,他们想要的是那种“基础设施问题由别人来处理”的感觉。并不是因为他们自己无法处理这些问题,而是因为处理基础设施根本不是他们从事软件开发的初衷。他们只是想简单地提交代码,然后让程序正常运行;当出现问题时,他们希望有一个统一的地方可以寻求帮助;同时,他们也希望能够看到一份自己能够理解的账单。

<更坦诚地说,真正需要的应该是这样一种平台:它能做出Heroku从未完全实现的那些架构决策——拥有自己的硬件资源,在网络层面上直接连接各种服务,提供统一的计费方式,让开发者能够专注于编写代码。

<这并不是怀旧情绪在作祟,而是解决这个问题所真正需要的措施。

另一种替代Heroku的选择

我最近一直在关注的是Atlasflow。这款平台使用裸机架构,提供了计算资源、Postgres数据库、兼容S3的存储服务以及队列系统,所有这些资源都位于同一个网络环境中,用户可以直接使用而无需进行额外的配置。而且只需要支付一笔费用即可。

<虽然我还没有在Atlasflow上运行过生产环境中的应用程序,因此无法评价它在高负载下的稳定性。不过这一点确实非常重要,我也不会假装它没有问题。

<但从架构设计的角度来看,Atlasflow才是迄今为止我所见过的、最能真正解决根本问题的方案。其他平台都只是让部署过程变得更简单而已,而Atlasflow却在思考:是否从一开始,集成工作就应该由开发者来负责完成。

<这个区别其实非常重要,它关系到整个系统的运作方式。

<<我从事生产环境应用程序的开发已经接近十年了,相信我,从几乎所有可衡量的角度来看,基础设施的环境确实已经得到了改善。但集成问题依然基本上没有得到解决。

Comments are closed.