Daily Tech Briefing
AI 科技速览

每天 5 分钟内学习 AI。获取最新的人工智能新闻,理解其重要性,并学习如何将其应用于您的工作。

AI 快讯
AI前线 · 2026/8/1 10:00:00
硬停止规则:从 3 个 HCM 单体应用到 120 个领域微服务

硬停止规则:从 3 个 HCM 单体应用到 120 个领域微服务

AI 中文解读
这家公司做了个大胆决定:不再修改那三个庞大又老旧的“单体”系统,而是立下一条硬规矩——以后任何新功能或修改,都直接拆出来做成独立的小服务。这样一来,迁移不再需要单独申请预算,而是跟着日常开发自然完成。短短几年,他们就从3个巨型应用拆出了120多个小服务,全程没有停机,连用户都没感觉到变化。这项操作就像把一座拥挤的旧大楼改造成多个小房间:不用每次改造都惊动全楼,而是谁需要新空间就单独盖一间,互不干扰。为了让这招行得通,他们配备了自动部署模板、统一的管理入口,还有能秒级回滚的“开关”来保证安全。对普通人来说,最直接的好处就是软件更新更快、系统更稳定,比如打卡记录这种敏感数据,再也不会因为系统“动手术”而丢失或暂停服务。这种不搞“大工程”而是“随用随拆”的思路,也给其他公司提供了新启发。
为什么资金问题其实并不是真正的资金问题2021 年 5 月,我和我在 Paycor(一家人力资本管理平台,现已被 Paychex 收购)的团队做了一个决定,那个决定最终塑造了我们平台未来五年的发展方向。我们停止了对单体架构的改动。当时共有三个单体应用:规模庞大、支持多租户,并且与我们负责的人力资本管理(HCM)产品的业务边界深度交织。我们早就想把它们拆分了。我们研究过扼杀者模式,也起草过一份为期多年的迁移计划。但这些计划始终未能获得资金支持。每个季度,迁移提案都要与能带来收入的功能需求竞争,结果总是败下阵来。于是我们尝试了另一种做法。不再单独做项目,而是制定了一条简单的规则:每个新功能、每个 Bug 修复、每次功能增强——任何原本会涉及单体应用的改动,现在都要拆分出来,创建一个新的领域服务。这种迁移将作为常规路线图工作的副产品自然发生,所需经费与其他所有工作共用同一预算。这是一种基于拉动机制的迁移。成本是切实存在的。在单体架构中原本只需要四个小时的变更,现在需要六个小时。我们将这部分成本分摊到数百个用户故事中,而不是试图将其打包成一项极有可能无法获批的资本支出申请。目前,我们在 Azure 上运行着 120 多个领域微服务,整个迁移过程实现了零停机。那三个单体应用仍然在运行,仅承载着无人需要改动的极小一部分功能,其余所有业务都已经完成迁移。本文将详细介绍该方法的实际运转情况:支撑这一过程的平台投资、我们被迫做出的架构选择、确保成本可控的成本优化措施,以及如果今天重新开始,我会采取哪些不同的做法。解锁三大平台,让基于拉动的迁移成为可能基于拉动的迁移——即每次产品驱动的代码变更都会独立拆分出一个服务,而不是让某个独立的程序按照自己的时间表进行迁移——从原理上讲似乎很简单。但在实践中,这取决于三项平台投资。因为我们刚开始时并不具备这三项条件,所以在最初大约一个季度的时间里,迁移过程相当艰难。一旦这三项条件都到位,迁移工作便变得顺理成章。Azure 上的按域订阅首次投资是结构性的。我们采用了“每个产品领域一个订阅”的模式。考勤系统有一个独立的订阅,薪资系统有一个独立的订阅,报表、排班、集成等功能也各自拥有独立的订阅。这在纸面上听起来有些繁琐。但在实际应用中,它为我们带来了三项超出预期的关键收益。首先是成本归属。考勤订阅的账单每月都会精确地显示该领域在云资源上的具体支出。我们不会将共享云成本在不同的领域之间进行分摊。每个团队都能看到自己的账单,并对此负责。这种架构还实现了影响范围隔离。无论是配置错误、脚本失控,还是过于严格的 IAM 新策略,所有问题都局限在该域的订阅范围内。在过去的五年中,我们从未发生过因配置变更导致的多域服务中断事件。此外,还有第三个较为隐性的效果:团队责任感。当工程师能够看到自己的资源消耗和平台占用情况时,他们在代码审查中会做出不同的决策。虽然这是一个隐性的结果,但已经在数据中体现出来了。是部署模板让订阅模式真正变得可用。当 DevOps 团队部署新服务时,该模板包含 Azure Kubernetes Service(AKS) 命名空间、数据库、Service Bus 和 Event Hub 配置、Key Vault、可观测性钩子以及网络配置。过去需要通过工单进行处理的、耗时两到四周的部署工作,如今已缩短为几分钟的自助服务。这是此次迁移带来的最大的行为变化。如果搭建新服务需要三周时间,工程师们就绝不会为此支付 50% 的前期成本;但如果新服务只需十分钟就能上线,他们就会愿意支付这笔钱。APIM 作为路由衔接层第二项投资是运维层面的。我们在预计要迁移的每个端点前都部署了 API 管理(APIM)。单体架构的端点和新的域服务都可以通过同一路径向 APIM 注册。流量分流由部署配置决定,而非客户端变更。我们可以先将 1% 的流量导向新服务,观察一天,然后再逐步增加比例。客户端完全不知道正在进行的切换。移动应用毫不知情,合作伙伴的公共 API 调用者也毫不知情。APIM 负责管理接口规范,新服务则实现了该规范。流量在我们指定的时间点顺利完成了切换。通过 Azure 应用配置实现功能开关,并使用 Redis 缓存封装器第三项投资属于战术性投资。我们需要一个生产环境可以信赖的功能开关层。Azure App Configuration 具备满足此需求的语义机制。但在我们的流量规模下,每次请求都调用该功能会带来高昂的成本。因此,我们构建了一个轻量级封装层,将值缓存到 Redis 中,并设置了比较短的 TTL 以及显式的失效触发机制。从应用程序的角度来看,功能开关检查等同于一次 Redis 查询,这几乎不产生任何成本。该封装层主要承担两项任务。第一项是渐进式发布:先为 1% 的租户开启某个功能开关,观察指标,再逐步扩展。第二项是近乎瞬时的回滚。如果某个版本出现异常,在 App Configuration 中切换该功能开关,几秒内即可传播到每个节点。渐进式发布是大多数工程师关注的部分。而近乎瞬时的回滚,则曾不止一次地拯救了我们。图 1:解锁三大平台,使基于拉动的迁移成为可能(图片由作者制作)HCM 服务水平目标(SLO)与考勤系统数据采集路径在人力资源管理(HCM)领域,有两个服务水平目标(SLO)几乎影响着我们做出的每一项架构决策。第一个是针对考勤系统的。当按小时计薪的员工打卡上下班时,我们绝不能丢失该条记录。对于本就入不敷出的员工来说,一次打卡记录的丢失就意味着一笔工资的损失。这方面绝不容许有任何误差。第二个是关于薪资系统的。一旦到了薪资处理时间,系统就必须正常运行。在薪资处理窗口期内发生系统停机,绝非单纯的不便,而是涉及合规报告的重大事件。这两项 SLO 推动我们做出了一系列具体的架构承诺。十个摄入来源,一份持久记录该考勤系统必须支持从大量设备和渠道接收打卡数据。目前,我们从以下十个来源采集数据:员工自助服务门户工作现场的实体考勤机休息室的自助终端面向零售和餐饮服务客户的销售点系统现场运营中的 iPad 应用程序iOS 和 Android 平台上的移动应用集成所使用的合作伙伴公共 API基于电话的系统管理员在管理界面中手动录入的考勤记录针对特定垂直领域的边缘设备每个数据源都有其独特之处。远程站点的物理时钟连接不稳定。合作伙伴 API 设有我们无法控制的速率限制。POS 系统会在业务淡季批量提交数据。移动应用会在离线时将数据放入队列,并在恢复连接后进行重放。无论通过何种渠道,每个数据源的首要任务都是将打卡数据写入 Service Bus 队列。随后,该打卡数据会从队列写入表存储,成为持久化记录。只有在持久化写入成功后,我们才会向数据源发出确认。这一流程(进入队列、写入持久化记录、确认)是 SLO 的核心。一旦数据拥有了持久化记录,我们就能从任何下游故障中恢复。在拥有持久化记录之前,我们无法确认该数据已经被接收。Event Hub 扇出根据持久化记录, Azure Event Hub 会向四个下游消费者广播数据:打卡处理:应用策略并计算工资事件。记录数据库:作为打卡数据的权威来源。报表:用于分析和合规性检查。最近打卡列表:用户打卡后在 UI 中立即看到的列表。每个消费者都从各自的消费者组中读取数据。它们独立扩展,独立发生故障,而且彼此之间不会相互阻塞。从对用户感知的影响来看,最近打卡列表是最重要的消费者。当员工在手机上点击“打卡”时,用户界面会在不到一秒钟的时间内确认接受或拒绝。该确认由持久化写入驱动,而非由下游操作的完成情况决定。手机不会等待工资计算完成。确定性回填下游消费者会出现故障。虽然不常见,但确实会发生。当它们发生故障时,我们会运行一个确定性的回填流,从持久化记录开始按顺序向前重放数据,将其写入正在恢复的任何下游系统。在消费端,重放操作具有幂等性:每个下游系统都维护着自己的水印,并且会跳过已经处理过的事件。其结果是,下游系统中断绝不会导致事件丢失。从事件被确认的那一刻起,它就已经保存在持久化记录中。无论下游发生什么情况,都能恢复。这正是将每个事件持久化存储所带来的实际收益。薪资系统薪资系统在美国的两个 Azure 区域(东部和西部)之间采用多区域 Active-Active 架构运行。这两个区域属于同一监管范围,区域间延迟较低,而且由同一运维团队负责。审计日志在两个区域中均得到了完整的保留。每个季度都会通过计划性的区域数据迁移测试故障转移功能。我们刻意没有将其他组件部署为多区域架构。哪些组件采用多区域部署、哪些不采用,这是一个预算层面的抉择。大多数组件完全能够适应单区域运行,而过度复制所产生的成本将超过其节省的成本。图 2:考勤系统数据摄取路径——十个数据源将数据发送到 Service Bus 和 Azure 表存储,成为持久化记录;Event Hub 将数据分发给四个下游消费者,并提供一个用于系统恢复的确定性回填流(图片由作者制作)如何度过上午 8、9 点的早高峰该考勤系统的日流量模式决定了其成本结构。当地时间上午 8 点至 9 点之间,在首班员工集中打卡的时段,各区域的打卡量高达数百万次,实际的流量峰值被压缩在约五分钟的时间窗内。这种流量形态既有好处也有坏处。好处在于它具有可预测性:我们确切地知道峰值何时到来以及规模有多大。坏处在于,若仅根据这种形态简单地配置云资源,成本会迅速攀升。该峰值还呈现出周模式:工作日流量模式相似,周末则明显降低(零售和酒店业仍有打卡需求,但不足以改变总体趋势)。我们的调度规则同时采用了日曲线和周曲线。如果我们将常驻容量按峰值进行配置,那么在 24 小时中,计算资源的利用率将有 23 个小时仅为 5%,而我们却要支
分享
阅读原文