《持续交付2.0系列五》软件系统架构 持续交付2.0 软件系统架构适合谁技术负责人、架构师、DevOps推进者读完能拿到一套大系统小做的方法论三种架构改造的实施路径以及技术债管理的实战策略一、引言为什么架构决定持续交付的上限很多团队在推行持续交付时CI/CD 流水线搭得很漂亮但发布依然痛苦——因为架构本身不支持持续交付。乔梁在第五章开宗明义地指出持续交付不只是一个工具链问题而是一个架构设计问题。一个无法独立测试、无法独立部署、无法快速回滚的系统再好的流水线也救不了。二、大系统小做原则2.1 持续交付的架构要求要让系统支持持续交付必须在设计阶段就考虑以下五个维度为测试而设计每个组件必须具备可自动化测试的能力接口清晰、依赖可控为部署而设计每个组件可以独立上线不需要全量部署为监控而设计每个组件有独立的健康检测指标故障可定位为扩展而设计热点模块可以独立扩容不影响其他部分为失效而设计单个组件故障可以快速回滚或降级不波及全局这五个为XX而设计是判断一个架构是否适合持续交付的基本标尺。2.2 系统拆分原则大系统小做不是新概念——1971年 David Parnas 就在论文中论证了模块化的价值。但在今天具体要遵循六个原则作为系统的一部分每个组件必须有清晰的业务职责能够被独立修改或替换高内聚、低耦合组件只了解必要的最少上下文信息合适的粒度大于类、小于整体系统通常以 jar/war/服务形式出现整体可交付拆分后整个系统仍然易于构建、集成测试和持续交付团队对齐拆分后的服务边界应与团队沟通边界对应平台同步拆分的同时必须同步建设构建、测试、部署、监测等自动化平台核心认知拆分不是为了拆分而拆分而是为了让每个组件都能独立交付价值。如果一个拆分后的组件依然不能独立测试和部署那这个拆分就是无效的。三、三大架构模式对比3.1 微核架构插件化微核架构把系统核心保持极简——只提供插件加载、扩展点和生命周期管理。业务功能以独立插件形式实现插件可以在运行时热插拔。优势核心不变插件可以单独构建、发布和回滚单元测试和 CI/CD 非常轻量化适合功能可选、需要快速迭代的产品局限插件间共享内核可能导致隐性耦合插件质量参差不齐可能影响核心稳定性3.2 微服务架构微服务把业务拆分为若干自治服务每个服务拥有独立代码库、数据库和部署单元通过轻量级通信REST/gRPC交互。优势天然支持独立扩容、灰度发布和容错配合容器化和服务网格可实现高度自动化的 CI/CD服务级别的技术选型自由度高代价分布式事务、网络延迟、运维复杂度显著上升需要成熟的 DevOps 与监控体系支撑警惕分布式单体——服务虽拆耦合依旧3.3 巨石应用单体巨石应用把全部业务逻辑、数据访问和界面封装在一个进程或部署单元内。适用场景业务边界清晰、团队规模小系统生命周期短或处于快速验证期资源受限无法承担分布式复杂度核心教训巨石应用本身不是原罪——不可拆分的巨石才是。一个好的单体架构内部层次清晰、模块边界明确完全可以支撑持续交付关键在于是否保留了未来演进的可能性。四、架构改造实施模式遗留系统改造是最常见的架构挑战。乔梁总结了三种实施模式4.1 拆迁者模式一次性重写根据当前业务需求重新设计架构并组建专门团队一次性开发全新系统完全替代旧系统。适合业务与技术债务极度错配、有充足资源投入、需求相对明确的项目。风险需求不明确导致重写方向偏差交付时间不确定团队经验不足一次性重写往往比预期慢 2-3 倍4.2 绞杀者模式逐步替代保持遗留系统基本不动通过不断开发新服务来实现新增功能逐步让旧系统失效并被替代。适合需要保持业务连续性、改造成本受限的环境。做法在旧系统前端加一层路由/网关新功能走新服务旧功能走旧系统逐步迁移旧功能到新服务旧系统最终被绞杀至消失代价需要维护双套系统接口兼容性管理复杂。4.3 修缮者模式渐进重构在同一系统内部对遗留系统的部分功能进行隔离和改进以新架构逐步替换旧功能。类似 Martin Fowler 的 “branch-by-abstraction” 技术。适合需要在保证业务连续性的同时实现渐进式重构。做法用抽象层隔离新旧实现逐步切换流量到新实现旧实现最终废弃4.4 数据库拆分无论选择哪种模式数据库拆分都是关键一步。核心原则数据所有权随服务边界迁移每个服务拥有自己的数据不共享数据库避免跨服务直接读写服务间通过接口交互不直接操作对方数据防止分布式单体服务之间没有物理隔离只是逻辑拆分五、技术债不是技术问题是业务需求5.1 技术债也是需求乔梁提出了一个关键观点技术债务必须写入需求 Backlog按优先级排期偿还。能跑就行的心态是对团队最大的不负责任。技术债会以更高昂的形式回报更高的事故成本故障频发、修复困难招聘困难优秀人才不愿维护屎山代码维护混乱没人敢动越堆越厚5.2 持续改进的 PDCA 循环每个迭代预留约20% 的时间用于持续重构和减债。使用 PDCA 循环Plan-Do-Check-Act驱动改进明确方向与挑战确定要改进的领域掌握当前状态用度量数据说话定义下一个目标状态设定可衡量的目标迭代改进执行改进措施并验证效果5.3 度量是为了改善不是考核古德哈特定律“当一项指标成为目标时它就不再是好指标。”度量体系的作用是识别改进机会不是追责工具驱动持续改善的文化不是 KPI 酷刑建立度量 → 改进 → 度量 → 改进的闭环六、业务落地行动计划评估当前架构用五个为XX而设计检查你的系统找出短板选择合适架构模式根据团队规模、业务复杂度、技术成熟度选择微核/微服务/单体制定改造路线图优先评估绞杀者模式——风险最低、收益最快建立技术债 Backlog把技术债当成正式需求来管理每个迭代预留 20% 减债时间搭建度量体系关注改进趋势而非绝对数值避免古德哈特陷阱培养安全文化失败是安全的、相互信任、持续改善——这是所有技术手段生效的前提七、总结复盘核心收获**“大系统小做”**是持续交付的架构基石——拆分是为了独立交付价值不是为了技术炫技没有最好的架构只有最适合的架构——微核、微服务、单体各有适用场景遗留系统改造首选绞杀者模式——风险最低、业务连续性最好技术债是业务需求——不还债的团队最终会被债拖垮度量是为了改善——不是考核的鞭子是改进的罗盘自我提问我的系统能否独立测试、独立部署、独立回滚如果不能卡在哪一环我们的架构改造是在拆迁还是在绞杀有没有更好的渐进路径技术债在我们的 Backlog 中有位置吗还是永远排在功能需求后面我们的度量指标是用来改善的还是用来考核的延伸阅读David Parnas, “On the Criteria To Be Used in Decomposing Systems into Modules” (1971)Martin Fowler, “Strangler Fig Application”赫伯特·亚历山大·西蒙《明日的弥尔顿》——关于复杂系统设计的经典论述最后一句话架构不是画出来的是改出来的。与其追求完美的蓝图不如用绞杀者模式一步步替换——每一次小步替换都是对技术债的一次偿还也是对持续交付能力的一次升级。下次面对要不要重构的纠结时问自己一个问题我能不能先拆出最小的一块让它独立交付