本文分享了扩展云和分布式应用程序的目标与策略,重点介绍了摩根大通(JPMorgan Chase)旗下Chase.com在云迁移过程中汲取的经验教训。
讨论围绕三个核心目标展开,详细阐述了实现这些目标的具体策略,最后说明了这些方法在实践中的落地方式。对于管理大规模系统的从业者而言,这些经验源自我们在摩根大通及其他金融机构多年来的实战积累,具有宝贵的指导意义。
在规划的时候,人们通常只会考虑两到三倍的负载增长。然而,一旦系统部署在互联网上,就无法控制入站流量的规模、时间或使用模式。任何事件(无论是源于合法业务增长,还是恶意攻击者的行为)都可能引发巨大的负载激增。这两种情形各自会带来截然不同的挑战。
安全控制措施可以阻止恶意流量,但当市场波动引发真实客户需求激增时,情况则有所不同。客户恰恰会在这些情况下需要访问金融交易服务。在系统压力下,多个组件可能同时发生故障;网络设备、负载均衡器、应用程序和数据库连接都可能同时中断。
目标
我们的云迁移聚焦于三大核心目标:以成本效益高且高效的方式实现弹性扩展、实现高韧性(这对金融机构尤为重要),以及提供卓越性能,防止因系统迟缓而迫使用户转向其他服务。
高效扩展
实现高效性需要分析客户的使用模式和行为。组织必须在保持弹性扩展能力的同时,发展预测能力。
流量整形(Traffic shaping)提供了一种识别高频率功能的方法论,从而能够有针对性地对关键应用进行扩展。
整体容量管理是另一个关键要素。简单地增加服务器并不能保证成功,还需要仔细权衡成本的因素。

流量模式与容量规划
流量模式是高效扩展的基础。平均流量代表了系统日常处理的基准水平。可预测的模式确实存在,例如,工资入账等周期性事件会促使客户查询账户余额。全年还会出现季节性高峰,这要求提前规划。
突发事件则会带来不同的挑战。DDoS 攻击频繁发生,其流量可能超过正常负载十倍甚至更高。攻击者利用的是与合法用户相同的云资源。组织必须在阻断这些攻击的同时,确保合法客户的真实交易仍能满足服务等级协议(SLA)。
基于已知模式进行合理的容量规划有助于预防运维方面的问题。然而,弹性扩展存在局限性:在扩展过程中,应用程序需要启动并建立与服务及数据库的连接,而建立连接需要时间。从实例启动到完全就绪,可能已经过去数分钟。若大量请求恰好在此期间涌入,系统将面临资源争用的问题。
因此,不能仅依赖弹性扩展,而应该全面考虑完整的运维图景,包括流量模式及相关因素。预留计算容量(Reserved compute capacity)可以应对这些挑战。预留资源能在需要时保证可用性,尤其在多租户共享资源池出现争用时更为关键。此外,预留计算还能带来成本节约。
成本管理需要进行持续关注。应该定期(如每月或每周)应用 FinOps 流程,而非偶尔为之。
超越单纯增加服务器的扩展
扩展不应该局限于简单地增加服务器。当发生扩展时,有一个根本性的问题,那就是,应用程序是否真的因为真实客户的需求而需要扩展,还是因为上游服务排队导致响应变慢?当线程等待响应而无法执行时,CPU 和内存的压力会上升,即使实际需求并未增长,也会触发弹性扩展。
这种场景要求我们在设计中考虑容错,并将其与扩展策略整合。断路器(Circuit breaker)在此过程中会发挥关键作用。当上游服务变慢或失败时,断路器可以防止应用无限期等待响应,而是强制设置超时限制:系统要么在限定窗口内收到成功响应,要么快速失败并继续处理。这种设计可避免线程耗尽、减少不必要的资源消耗,并防止错误地触发扩展。如果没有断路器的话,缓慢的依赖项可能会引发全系统的性能退化,导致弹性扩展,从而添加更多无法解决根本问题的服务器。
高韧性
韧性(Resiliency)要求为不可避免的系统故障做好准备。早期检测和随时执行故障转移程序至关重要。然而,为所有组件实现 100%的可用性既不现实,也无必要。

基础设施可根据关键性分为四个层级。关键(Critical)类的组件必须尽可能接近 100%可用。DNS 就属此类,无论网站架构多么完善,DNS 如果出现故障将会导致所有访问中断。
可管理(Manageable)层的组件在发生故障时可通过故障转移维持运行,目标为“四个九”的可用性(99.99%,即每年可接受约 52 分钟的停机时间)。
可容忍(Tolerable)层的组件具备内置韧性。例如,缓存长期数据的令牌服务,若服务在缓存有效期内不可用,系统仍可使用已缓存的数据继续运行。
最后,可接受(Acceptable)层的组件允许有限的数据丢失,比如,某些日志系统。韧性目标由影响的严重程度决定。
性能
性能会显著影响用户体验和基础设施成本,但并非所有应用程序的表现完全相同。通过部署接入点(Point of Presence, PoP)可以提升用户体验,因为它对网站延迟(尤其在移动设备上)尤为敏感。
速度至关重要,因为它能建立用户信任,用户期望更快、更好的体验。谷歌等搜索引擎已经认识到这一点,并将速度纳入其排名算法。在网络连接受限的场景下,移动端性能尤为关键。从基础设施角度看,客户完成相同任务所花费的时间越少,运营成本就越低。
我们通过实施全面的性能策略,从初始部署到完整架构落地,系统延迟降低了 71%。这些策略可适配其他业务场景。
五大核心策略
架构方法围绕五个重点领域展开:多区域部署、高性能优化、全面自动化、具备自愈能力的可观测性,以及强大的安全性。
多区域部署
多区域架构通过隔离和分段实现功能化的解耦。这种方法有助于管理区域故障、可用区故障和网络故障,并限制故障的爆炸半径(blast radius)。面对 9400 万客户,可用区级别的故障可被限制为仅影响一小部分用户,而非全部用户。
实现多区域架构需要解决 DNS 管理的问题,因为不同区域拥有独立的负载均衡器,需要协调一致。还需要确定区域间流量的调度策略。在包含多个可用区的区域内,也需选择流量的分配方式。
可用区故障
假设一个负载均衡器将流量分发至同一区域内的两个可用区。两个应用均报告健康状态,可用区看似正常,流量持续流入。然而,如果其中一个可用区的应用与后端系统连接异常,而另一可用区正常,流量仍将流入受损的可用区。若应用虽实现了就绪(readiness)和存活(liveness)探针,却未将依赖系统状态纳入健康检查,那么就有可能出现问题。缺乏适当的反馈机制时,负载均衡器会继续路由流量,导致应用失败。

针对这种情况,解决方案包括将依赖系统的健康状态通过就绪或存活探针反馈给负载均衡器,或采用基于代理的重路由机制将流量导向正常的可用区。这需要有效管理内外部故障,以应对应用停机。
区域性的故障
在多区域部署中,我们依赖统一的区域健康脉搏检查(每 10 秒执行一次),以确保对区域健康状况的一致性和及时可见性。在这里,关键的决策在于,故障是否需要完全切换至备用区域,或者降级服务是否可接受。降级服务的可行性取决于应用的分段情况。若关键服务(如仪表盘首页)失效,则需要故障转移;若非关键组件失效,那么可以继续运行以避免更大的影响。但故障转移会引发“惊群效应”(thundering herd),例如,整个区域失效时,重定向流量突增可能压垮剩余区域,而自动扩展需要时间才能提供额外的容量。健康检查标准(包括失败与成功阈值)决定了对应的响应策略。
多区域的挑战
跨区域的数据复制与确保数据一致性是主要的关注点。当数据中心位置有限而客户遍布全国时,客户分片(customer sharding)是一种可行的方案:将客户按地理位置分片,并由就近的数据中心提供服务,这样可以减少复制的需求,并简化架构。
状态管理需要战略性的决策。为活跃会话维护会话亲和性(session affinity),并在必要时支持故障转移,这有助于高效运行。
高性能
高性能对用户体验至关重要。良好的性能如同可靠的拨号音,用户期望即时响应,不容延迟。边缘计算是实现性能目标的主要手段。现代网站具有复杂的用户界面,内容密集。我们可将静态内容卸载至靠近客户的入网点(Point of Presence,PoP),而源服务器(origin server)仅处理动态操作和关键服务,如登录、账户、支付等。

流量整形(traffic shaping)可以对流量进行分类。关键流量指的是支撑业务运营的核心功能,比如,客户日常的登录、余额查询和支付。分配给关键服务的资源必须始终保持运行。在压力条件下,即便其他流量出现降级也是可以接受的。
内容分发
地理分布会显著影响性能。如果每次资源请求都需要跨越很长的距离,物理网络的屏障将会造成显著的延迟。如果相同的内容已在 PoP 缓存,检索可在 100 毫秒内完成,远优于访问源站所需的较长响应时间(比如,大于 500 毫秒)。性能提升的同时会带来安全方面的收益,因为恶意的流量可以在边缘被拦截。
“最后一公里连接(last-mile connectivity)”的问题值得关注。互联网通信涉及多个网络跳转。边缘计算改变了这一模式,从用户到边缘节点通常只需要一跳,再结合优化的网络传输,这样所带来的效率远高于标准的 ISP-to-ISP 连接。
移动应用也有优化的空间。移动设备具备本地存储,可用于缓存网络解析结果、配置设置和预抓取的内容。
自动化
自动化是关键的战略元素。在整个流水线的各个阶段实施全面自动化可带来巨大收益,这需要涵盖部署、基础设施供应、环境配置、集成自动化操作的健康检查,以及整体的流量管理。

架构不能止步于文档。通过创建“带有倾向性的(opinionated)”架构模板,可以帮助团队构建自动继承架构标准的应用。应用通过基于清单(manifest)定义进行自动化部署,这样能够让团队聚焦业务功能,而非基础设施工具的复杂性。
基础设施“重铺”
基础设施“重铺(repaving)”是一种高效的实践,即在每个迭代周期系统性地重建基础设施。自动化的流程会定期清理运行中的实例。这种方式能够通过消除配置漂移(configuration drift)来增强安全性。当存在漂移或需要应用补丁(包括零日漏洞修复)时,所有更新均可系统性地实现。
长期运行会导致资源陈旧、性能下降和安全漏洞。我们可以定期(如每周或每两周)自动重建环境,步骤大致如下:先优雅地移除流量,再重建环境并重启服务,从而保障运维的稳定性。
重铺实现涉及多个组件:自动化脚本监控实例的生命周期;基于时间的有效性触发器会移除路由,阻止新请求进入但允许现有请求完成;随后关闭实例、清理节点并创建新实例。创建新实例时,可以使用更新后的镜像,以解决零日(zero-day)漏洞并添加安全补丁,也可以仅简单地重建实例。具体的操作由策略决定。所有流程均自动化完成,在重铺前会移除流量,确保对客户不会产生任何影响。
自动化故障转移
具备优雅降级能力的自动化故障转移需要考虑活跃的会话。对于正在进行处理的客户,会话的处理方式不同于新的会话,需要进行特殊路由。除此之外,必须防止故障转移循环,如果两个区域均不健康,持续切换只会加剧问题。不同场景对延迟容忍度不同;非关键服务故障时,可在受影响区域继续运行。
可观测性与自愈能力
可观测性要求对观测到的事件进行自动化的响应。云环境在各组件中会产生大量事件,比如系统事件、基础设施事件和应用事件。所有的可观测事件都需要自动处理。自动化会通过无服务器函数与可观测性进行集成,也就是在事件触发后,函数自动执行,并且会根据预设的条件切换在哪个区域执行。
数据库问题会触发独立的数据库切换函数;维护活动可以触发函数以屏蔽特定区域或虚拟私有网络(virtual private cloud,VPC)。这些示例场景展示了如何实现自动化行为,同时确保与可观测性的集成。仪表盘监控能够提供辅助价值,但不应该作为主要的响应机制。
健康检查
健康监控需要在多个层级进行。在应用层,健康判断可能涉及复杂的评估,不仅要检查应用本身是否正常运行,还包括与数据库、缓存及其他系统的连接是否通畅。健康检查器内部可以包含复杂的逻辑,但返回状态必须简单,仅用布尔值表示健康或不健康状态即可。
应用内的健康检查要向上传播至可用区这一层级,它要检查所有的实例。然后,这个信息转移至 VPC 层级,以评估整体 VPC 的健康状况,最终输入全局的路由器。每一层级均通过简单的布尔指标实现自动化健康评估,从而支持快速决策。该方法通过系统性健康检查以实现自愈的能力。
决策标准
我们可能会遇到如下的场景,告警指示节点不可用且容量受损,这可能是供应商的问题,流量需要从受影响的 VPC 进行重定向;应用告警显示延迟问题且性能受损,组织需要根据业务需求决定是继续提供降级服务,还是满足服务等级协议(service level agreement,SLA)的要求。在这样的场景中,选择降级服务意味着接受较慢的性能,而非切换至可能存在相同问题的其他可用区。

“灰度故障”(gray failures)指的是故障确定存在但连接仍存在的模糊故障场景。网络相关的故障更难诊断。当某项业务功能受损时,可以考虑将流量重路由至健康的可用区。可以基于可观测性数据执行多种应对措施。
健壮的安全性
安全需要采用零信任模型的分层实现。每一层必须独立运作,假定其他层均可能失效。客户端设备可能会被恶意软件攻陷;边界安全功能需要在边缘实现过滤和 Web 应用防火墙;内部网络需要分段和隔离;容器安全方面,需要进行镜像扫描并采用最小权限原则;应用安全方面,需要确保正确地认证与授权;数据安全方面,要实施加密与隐私控制。各层之间要实现互相强化。
迁移
文化转型是成功迁移的基础,因为云运维与传统的企业自建系统存在根本性的差异。云服务商会持续更新服务,网络策略在不断演进,浏览器也在不断变化,诸多因素都要求我们持续适应。Well-Architected Framework 及相关原则在这方面提供了指导。
“谁构建、谁拥有、谁部署”的所有权模型将责任赋予了应用团队。人为错误与疏忽不可避免,而自动化可以确保一致性。
测试与验证
测试方法各异。Chaos Monkey 等工具通过向运行中的系统注入故障实现反应式测试;失效模式与影响分析(FMEA,Failure Mode and Effects Analysis)则通过系统性组件评估进行预测性分析,识别潜在的故障并制定缓解策略。这两种方法均有它的价值,但 FMEA 更适用于在各应用层进行全面测试,确保能够开发分析与缓解策略。
公司开发了名为 TrueCD 的 CI/CD 方法论,这是一套包含了十二个步骤的自动化流程,相关文档已经在官方博客进行详细阐述。该流程类似于航空业的飞行前安全检查。
抽象层
从企业自建环境向云迁移会影响应用的架构。应用包含了大量的业务逻辑,持续变更可能对业务运维产生连锁影响。抽象层可以最大限度地减少此类影响。该架构方法可在单云、多云、自建环境或混合环境中灵活选用业界最佳组件。Dapr是一个广受认可的开源框架,支持多云架构。
迁移客户流量
大型应用的迁移无法一蹴而就。在初期,可以先在内部用户群体中验证系统,使应用趋于稳定。压缩时间表往往会适得其反,因为某些问题和使用模式需要长期观察才能发现。应用需要充足的运行时间以完成优化。
面对庞大的功能集,在有限时间内完成所有功能可能不现实。将系统拆分为离散应用集可以应对该挑战。在迁移的各个阶段,可逐步将小比例的客户群体进行迁移,最终再实现全面迁移。
结果
这些策略的实施带来了可衡量的成果:显著降低成本,性能指标大幅提升,平台在对比分析中名列前茅。Dynatrace 的公开报告对美国银行网站进行了比较,它指出实现亚秒级(<1 秒)响应的站点代表了最优的性能。
结论
从这些策略中可以提炼出一些关键的考量因素。权衡是不可避免的,我们需要综合考虑成本与性能,同时不损害其他的需求。例如,在多区域架构中,需要评估缓存复制策略:是在单区域还是多区域维护缓存?运维的复杂性随云架构组件的增多而上升。降低复杂性、减少应用监控中的人工干预至关重要,而自动化是实现这一目标的关键机制。
控制故障的爆炸半径始终至关重要。站点必然会遇到各种问题,组件难免失效。关键在于故障发生时的影响范围,是波及所有客户,还是仅限一小部分?这一关注点至关重要。我们必须建立面向行动的可观测性,并与自动化操作紧密关联起来。
所有决策必须以客户为中心。业务运营服务于客户。请思考“拨号音体验”:拿起电话,用户期望立即听到拨号音。应用亦应如此,用户打开移动应用,理应立即看到结果。
核心原则:智能扩展,保持可靠性。当下一次流量激增不可避免地到来时,系统弱点必将暴露出来。这些策略的直接目标在于,当流量激增时,关键组件必须能够保持运行,核心系统必须维持响应能力,客户必须像往常一样获得即时响应。
原文链接:
Scaling Cloud and Distributed Applications: Lessons and Strategies





