← 返回蜂巢洞察

在生产环境中进行部署时会发生什么?一场幕后揭秘之旅

你提交代码后,几分钟后,这些代码就会真正开始为用户提供服务。 在这两个时刻之间,有一系列复杂的流程在运转:代码构建、生成相应的成果文件、数据库迁移、健康检查以及流量分配调整。每一位生产工程师都依赖这一整套流程,而许多团队至今仍然亲自负责这些工作的执行。 部署基础设施如今已经悄然成为一种运营负担。它最初只是出于技术上的必要性而存在的——因为当时没有其他可行的解决方案,所以每个团队都必须自行搭建这套系统。 如今,这已经成为另一个需要工程师维护的系统,它会消耗大量的值班时间、开发资源,甚至还会在凌晨两点占用本该用于更重要工作的精力。 在这篇文章中,我们将详细探讨一次实际的生产环境部署过程:从代码构建

你提交代码后,几分钟后,这些代码就会真正开始为用户提供服务。

在这两个时刻之间,有一系列复杂的流程在运转:代码构建、生成相应的成果文件、数据库迁移、健康检查以及流量分配调整。每一位生产工程师都依赖这一整套流程,而许多团队至今仍然亲自负责这些工作的执行。

部署基础设施如今已经悄然成为一种运营负担。它最初只是出于技术上的必要性而存在的——因为当时没有其他可行的解决方案,所以每个团队都必须自行搭建这套系统。

如今,这已经成为另一个需要工程师维护的系统,它会消耗大量的值班时间、开发资源,甚至还会在凌晨两点占用本该用于更重要工作的精力。

在这篇文章中,我们将详细探讨一次实际的生产环境部署过程:从代码构建开始,到生成成果文件、进行数据库迁移、进行健康检查,再到滚动更新和回滚操作。同时,我们也会分析为什么平台即服务工具能够帮你完成这些步骤中的大部分工作,以及如果团队继续自行处理这些任务会付出什么样的代价。

目录

代码构建:将代码转化为可运行的形式

部署过程并不会直接发送原始的源代码,而是会生成代码构建后的结果。在构建阶段,你的代码会被转换成服务器能够运行的形式。

具体的实现方式取决于你使用的技术栈。对于Java或Go项目来说,代码会被编译成二进制文件;对于JavaScript前端应用,代码会被打包并压缩;而对于Python应用程序,则需要解决其依赖关系并确定所有必要的依赖库版本。在大多数现代开发环境中,所有这些步骤最终都会被封装到一个容器镜像中,这个镜像就包含了你的应用程序以及它运行所需的所有资源。

构建阶段还会执行各种测试。单元测试、代码格式检查以及安全扫描都会在这个阶段进行。如果其中任何一项测试失败,部署过程就会立即停止,从而避免影响到生产环境。这是发现缺陷的最有效途径——一次构建失败只会耗费几分钟时间,而一次部署失败却可能会让你失去客户。

代码部署的各个阶段

那些自己搭建部署流程的团队会在这上面投入大量精力。他们需要维护构建服务器、缓存依赖关系,还要解决那些经常出问题的测试工具带来的问题。

然而,所有这些工作其实并不会直接产生新的功能或成果。它们纯粹属于维护工作,而且这种工作永远没有尽头。而PaaS平台会将整个部署流程内嵌到其中:你只需推送代码,平台就会自动识别你所使用的语言,每次都会以相同的方式构建代码;一旦出现任何问题,系统会立即反馈错误信息。虽然构建过程依然会发生,但你的工程师们再也不用为这些工作耗费大量的时间了。

成果物:被冻结在某个时刻的单一版本

构建过程的最终结果被称为“成果物”。它可能是一个容器镜像、一个编译后的二进制文件,或者是一个压缩包。无论采用哪种格式,成果物的唯一作用就是确保其内容的准确性——它代表的是你的应用程序在某个特定时刻的精确版本。

这一点的重要性远超表面看上去的那样。只有通过所有测试的成果物才能被部署到生产环境中。如果在测试和发布之间重新构建代码,就有可能导致最终发布的版本与之前有所不同:某个依赖库可能已经更新了,或者某些配置选项也发生了变化。“在测试环境里可以运行”这句话往往意味着“我们实际上构建了两次代码,得到了两种不同的结果”。

优秀的部署流程会只构建一次代码,并将相同的成果物应用于每一个部署阶段。这些成果物会被赋予版本号并存储在注册系统中,这样以后就可以随时取出某个特定版本的成果物重新进行测试或部署。这种存储的历史记录也是实现回滚功能的关键所在,我们稍后还会详细介绍这一点。

在PaaS平台上,处理成果物是默认就具备的标准流程。每次部署都会生成一个带有编号的版本,平台会负责存储、跟踪这些版本,并能在需要时恢复它们。你根本不需要专门设计注册系统的相关策略,也不用编写部署脚本或指派专人来管理这些成果物——这些功能都是平台本身就内置好的。

数据库迁移:最危险的部分

在新代码正式上线之前,通常还需要对数据库进行相应的修改。也许新版本需要添加新的列或表结构,这些修改就被称为“数据库迁移”,而它们也是大多数部署过程中最危险的部分。

为什么呢?因为代码很容易被替换,但数据却无法轻易更改。如果你部署了一个有问题的代码版本,可以随时将其替换掉;但如果数据库迁移操作导致了数据损坏或丢失,可能就没有任何办法能够恢复数据了。此外,数据库迁移还会带来一段复杂的时间窗口——在这段时间内,旧版本的代码和新版本的代码可能会同时访问同一个数据库,因此这两个版本都必须能够适应当时的数据库结构。

安全的做法是确保数据库迁移操作具有向后兼容性。首先添加新的列或表结构,然后部署能够同时处理新旧两种结构的代码,最后在后续的版本中再删除旧的列或表结构。虽然这样需要多几个步骤,但每个步骤本身都是安全的。

PaaS平台无法替你完成数据迁移工作。没有任何工具能够真正理解你的数据的含义。但是,一个优秀的平台会为数据迁移操作在发布流程中指定明确的位置,按顺序执行这些操作,并详细记录每项操作的执行时间与内容。这样的机制可以有效避免那种有人手动执行数据迁移却忘记通知团队的情况,从而避免由此引发的故障。

健康检查:验证新版本的可用性

当新版本启动后,平台并不会盲目信任它,而是会对其进行检测。健康检查其实是应用程序中的一个小型接口,通常只是一个能够返回“正常”响应的路由。平台会反复调用这个接口进行检测。如果应用程序能够正常响应,就说明它的运行状态是正常的;否则,平台就会认为出现了问题。

通常会有两种类型的检查。一种是“准备就绪检查”,用于确认应用程序是否已经准备好接收请求;另一种是“运行状态检查”,用于判断应用程序是否仍在正常工作,或者是否需要重新启动。这两种检查的区别非常重要——一个应用程序可能处于运行状态,但并不具备处理请求的能力,比如当它还在加载缓存数据时。

健康检查是确保新版本能够顺利部署的关键机制。在证明新版本能够正常处理请求之前,任何流量都不会被路由到该版本上。如果没有这种检测机制,就会导致真实用户使用那些在启动时还会出现故障的应用程序。

所有正规的PaaS平台都会自动执行健康检查。你需要定义相关的接口地址,而平台会负责处理所有的检测流程、超时设置以及决策逻辑。那些自行开发这类功能的团队通常需要通过反复试验来调整这些参数,而这个过程往往会耗费大量的工程时间,而且这些问题在几年前就已经被业界解决了。

滚动更新:在应用程序运行过程中更换其核心组件

现在来到最棘手的部分——你的旧版本目前正在为真实用户提供服务,因此你必须在不中断任何请求处理的情况下替换它。最常见的解决方案就是使用滚动更新机制。

其具体运作方式如下:假设你有四个副本在运行同一个应用程序,平台会先启动其中一个新版本的副本,并等待其健康检查结果合格;之后才会将部分请求流量切换到这个新版本上,同时关闭一个旧版本副本。这样逐个替换下去,最终只剩下新版本在运行。用户根本不会察觉到任何变化,因为在任何时刻都有足够的正常运行的副本在为所有用户提供服务。

有些团队也会采用一些变通方案。例如,“蓝绿部署”策略会在新版本和旧版本并行运行的基础上,一次性将所有流量切换到新版本上;而“金丝雀发布”策略则会先让一小部分用户使用新版本,以便及时发现潜在问题。

如果手动执行这些操作,就需要编写相应的协调逻辑、管理负载均衡规则,并处理各种可能出现的异常情况。这需要耗费数月的工程时间来构建这样的系统,而且之后还需要持续进行维护工作——而这些功能在PaaS平台上都是默认提供的。因此,在使用PaaS平台时,你可以直接获得无中断的更新体验,而无需自己的团队花费精力去实现这些功能。

回滚机制:最后的保障措施

有时候,新版本虽然通过了所有的检测,但仍然会引发实际问题,导致错误率上升或页面无法正常显示。在这种情况下,速度就变得至关重要了,而最快的解决办法往往不是发布新的补丁,而是进行回滚操作——重新部署那些已经被证明能够正常运行的旧版本代码。

正因为如此,经过版本控制的冻结代码才显得如此重要。只有当旧版本已经被存储、测试完毕并且可以直接运行时,回滚操作才能迅速完成。那些在压力下试图从旧的提交版本重新构建系统的团队,其实是在最糟糕的时刻进行冒险。

在大多数PaaS平台上,回滚操作只需要执行一条命令或点击一下按钮即可完成。这些平台会保存你的发布历史记录,并能在几秒钟内恢复到任何之前的版本。正是这一功能,为许多值班工程师节省了大量时间。

当你不需要PaaS时

将部署工作交给PaaS平台确实是一个很有意义的选择,但这种做法并非适用于所有情况。对于某些团队来说,拥有自己的部署流程并不会增加额外的负担,相反,这反而是一种经过深思熟虑且合理的工程决策。

当合规性成为必要条件时

金融、医疗保健、政府等领域往往受到一些特殊规定的约束,而这些规定是标准PaaS平台无法直接满足的。数据存储要求可能会明确规定你的应用程序必须使用哪些物理基础设施;审计要求也可能需要某种特定的溯源机制和访问日志记录功能,而这些都是托管型平台所不具备的。

在某些情况下,安全控制措施甚至需要延伸到构建环境本身,而不仅仅是运行时环境。在这种环境下,拥有自己的部署流程确实会带来一定的成本,但这也是在这些特定行业中正常运营所必须付出的代价。

当部署本身就是你的核心产品时

如果你的公司销售部署相关的基础设施、CI/CD平台、发布管理工具或内部开发平台,那么你的部署流程根本就不是什么负担,而是你的核心产品之一。

负责维护这些平台的工程师们所做的其实就是在开发产品,而不是在做无关紧要的工作。对于那些大型组织中的平台工程团队来说,他们的明确职责就是为其他数十个内部团队提供部署支持。在这两种情况下,“为什么我们要自己来处理这些事情”这个问题都有一个显而易见的答案:因为这就是我们的工作内容。

当你的基础设施确实与众不同时

大多数PaaS平台都是为无状态Web服务和标准容器化工作负载优化的。如果你的系统超出了这些平台的适用范围——比如需要使用GPU集群、实时系统且对延迟有严格要求、采用混合式的本地与云部署方式、或者需要进行硬件在环测试——那么标准PaaS平台可能根本无法满足你的需求。

试图将这种特殊的部署需求强行适配到PaaS平台上,往往会导致更多的麻烦和障碍;而根据你实际面临的限制条件来专门开发定制化的部署工具,反而会更加高效。

以上三种情况都有一个共同点:那就是具体环境的特殊性。那些决定自己拥有部署流程的团队,通常能够清楚地说明为什么PaaS平台不适合他们的需求。如果他们的回答是“我们一直都是这么做的”或者“我们喜欢拥有控制权”,那么这些理由确实值得质疑;而如果回答是“我们的合规性要求必须如此”或者“我们就是从事这个领域的业务”,那么这些原因就显得非常合理了。

你还应该自己来运营这些流程吗?

PaaS并不会让这些步骤消失。构建过程依然会进行,生成的各种文件也会被保存下来,迁移操作依旧需要执行,健康检查也会继续进行,流量分配也依然是按批次进行的。将这些流程抽象出来并不会消除它们,而是使它们标准化,并将它们的维护工作交由专门负责产品部署的团队来处理。

每个产品团队现在都应该认真思考这个问题:为什么我们还要自己来构建和运营这些流程呢?十年前,定制化的部署流程是不可避免的;但今天,这已经是一个可以自主选择的事情——而对大多数团队来说,这个选择其实是错误的。每花一个小时去调试那些容易出现故障的构建工具、调整健康检查的超时设置,或者修补调度脚本,其实就是在浪费客户为你的产品支付的费用。这样的定制化流程并不会让你区别于竞争对手;他们的部署方式和你的一样。

你需要了解这些流程的具体运作机制,因为半夜两点需要处理紧急情况时,这种了解是必不可少的。但仅仅了解这些机制,并不足以成为你自己来维护这些流程的理由。“我们自己构建了部署系统”这句话已经不再是一种荣誉的象征,而恰恰说明你的团队正在维护一个实际上没有客户的“额外产品”。除非部署基础设施真的是你们的核心业务,否则就把这些工作交给专业的平台吧,让工程师们把精力放在他们真正擅长的事情上。

希望你喜欢这篇文章。你可以通过在LinkedIn上与我联系

相关文章

技术实践

如何在没有服务器的情况下为静态网站添加动态功能

静态网站目前正受到人们的青睐,这是有原因的。一个包含HTML、CSS和JavaScript文件的文件夹,加载速度很快,托管成本也很低,而且几乎不可能出现故障。 像 Astro 、 Eleventy 和 Hugo 这样的工具,能够利用Markdown文件和模板帮您生成这样的网站结构。而Netlify、Vercel以及Cloudflare Pages等托管服务,则可以通过内容分发网络来提供这些生成的网站内容,而且通常还是免费的。 不过,您的网站还需要具备实际的功能。读者可能想要留下评论,或者有人想通过电子邮件与您联系。也许您还想实时显示价格信息,需要用户登录后才能查看某些页面,或者在网站发布之前收

阅读全文
技术实践

即时响应机制与循环处理机制:开发者指南

对许多开发者来说,人工智能的工作流程大致是这样的:编写一个提示语,获取模型给出的回复,提取其中有用的信息,然后继续下一步工作。这种工作流程涵盖了范围相当广泛的任务,从总结文档内容到起草电子邮件,再到解释代码逻辑。然而,当某项任务需要多个步骤、外部数据的支持,或者决策结果取决于模型刚刚返回的信息时,这种工作流程就会遇到问题。这时,开发者不得不手动重新编写提示语,手工调整输出结果,去做那些本应由系统来完成的工作。在这种情况下,单一的提示语就不再是一种有效的工具了,而设计一个能够多次向模型发送请求的系统,才成为了真正需要完成的任务。有两种术语可以用来描述这两种不同的工作模式: ** “提示语工程”是

阅读全文
技术实践

人工智能评估工程:从零开始构建一款可用于生产环境的大型语言模型评估平台【完整使用手册】

一个令人印象深刻的演示与一个值得信赖的系统之间的差距,其实是通过各种评估来衡量的。 我想先讲一个目前正在数百个工程团队中发生的真实案例。 有一个团队为法律研究开发了一个RAG应用程序。他们用40个精心挑选的问题对该程序进行了测试,结果看起来很不错,于是便向合作方展示了这个系统。合作方对它印象深刻,随后便决定将其正式投入使用。 然而在系统投入生产三周后,一名法律助理发现其中一个答案错误地引用了某项法规。工程团队查看了相关数据,发现“准确性得分”为0.91,这个数值看起来是正常的;他们还检查了答案的相关性,结果也符合标准。 但他们忽略了一个重要的指标:即“上下文完整性”。这个指标用于判断系统是否检

阅读全文
技术实践

如何让你的副业项目被人们注意到,并吸引到愿意付费使用的用户

2022年,我在业余时间开发了一个小型微服务产品,最终以几千美元的价格将其卖了出去。如今,有了人工智能工具的帮助,开发这样的产品可能会更加容易。 但真正发生巨大变化的是获取关注的成本,而不是开发软件本身的成本。 我认为,在2026年,产品的分发渠道将比开发本身更为重要。在这篇文章中,我会与大家分享我在产品开发过程中所学到的经验,并试图劝阻大家在开始下一个项目之前,先不要急着直接投入编码工作。 读完这份指南后,你应该能够掌握一些实用的方法和思路,这些方法可以帮助你将自己那些充满热情的项目推向市场。 需要明确的是,这篇文章主要是针对那些正在开发数字产品的人,尤其是软件产品。不过,这些概念同样适用于

阅读全文