ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

哲学驱动式软件架构法:基于易经三大原则的实践指南

哲学驱动式软件架构法:基于易经三大原则的实践指南 先把话说在前面这篇不是标题党也不是为了把某个玄学概念硬往技术上套。我是在实际负责过几套中大型业务系统的架构演进之后回过头来读这一节内容才意识到“基于易经的软件架构系统观”这个说法其实比它听起来要实用得多。你看到的这个标题是“哲学驱动式软件架构法——基于易经的软件架构系统观与实践2.10.1 ~ 2.10.3”单看可能会觉得抽象甚至有点“神叨”。但如果你拆开看会发现这套方法本质上是在回答一个非常现实的问题当业务方的需求每天都在变技术栈每个月都可能要调整你作为架构师到底凭什么做决策你的边界感从哪里来这一节内容讲的是哲学如何成为一种架构决策的底层框架具体来说就是借易经里“不易、变易、简易”这三个核心原则去重新审视软件架构里的职责划分、演进方向、以及复杂度治理。这不是代替DDD、洋葱架构、微服务那一套方法论而是给这些方法提供一个更上层的判断依据。适合正在做架构决策的技术负责人被业务需求追着跑的系统设计者以及那些觉得“架构全靠经验”但想找到一些可传承方法论的人。接下来我会把这部分的三个小节逐段拆开结合我自己的实践经历讲清楚它到底说了什么、能解决什么问题、以及怎么落地到你的项目里。1. 这套方法的底层逻辑——易经三大原则在架构中的映射先说一个现象我和很多同行聊架构的时候大家聊的是限流、熔断、分库分表、事件驱动聊的是技术选型。但我发现真正拉开架构水平差距的往往不是这些具体的术而是做判断时那一层说不清道不明的“道”。这一节内容最核心的贡献就是把这层“道”用易经的语言体系清楚地表达了出来。它把整个软件架构系统观建立在三个相互关联的原则之上不易、变易、简易。这三个词不是玄学放到软件系统里每个都有非常明确的指代。1.1 不易寻找架构的锚点所谓不易是指在一个多变的环境里有些东西是相对稳定、不应该轻易变化的。对软件架构而言这个“不易”通常指系统的职责边界、核心领域模型、以及不可变的基础约束。比如你做一个电商系统“订单”这个概念无论业务怎么玩它背后的核心状态机——待支付、已支付、已发货、已完成——是相对稳定的。这就是“不易”的那部分。架构师的重要工作之一就是通过业务分析和领域建模把这些稳定的部分识别出来然后坚定地守住。我见过很多失败的架构改造问题不是技术不够而是把不该变的部分一起翻新了。比如为了追求极致的性能把订单表结构推翻重建连状态机的语义都改了结果就是全链路联调三个月上线后各种边界case爆雷。如果用“不易”这把尺子去量就会清楚表结构调整是变易层面的事状态机语义是本质层面的问题不能一起动。1.2 变易接受并驾驭持续的变化变易强调的是系统永远处于变化之中架构师不能幻想“设计一个终极不变的系统”。业务的促销规则、用户的使用习惯、底层基础设施的迭代这些都在不断变化。在架构上变易的体现就是演进式设计。你做的每一个设计决策都应该给未来的变化留出空间。这倒不是说非要搞微服务、搞插件化而是说你至少要在核心模块的边界上保持足够的清晰度让变化发生时影响可以被控制在局部。这一节内容里最值得反复琢磨的一句话是变易不是架构的敌人不变才是。一个架构师的成熟度恰恰体现在他能不能在变化中做判断而不是试图消灭变化。1.3 简易以复杂度为代价的清醒简易不是简单而是“简而不陋”。它指的是在满足业务需求的前提下架构的复杂度应该尽量低让每个参与系统建设的人都能快速理解它。这个原则跟《易经》里说的“乾以易知坤以简能”其实是一个意思——最高的效率来自清晰和简单。放到软件架构里就是我们要警惕过度设计。我见过有团队从头搭建微服务基础设施网关、配置中心、链路追踪、容器编排全套上马结果业务只有三个模块团队只有五个人。这就是典型的违背“简易”原则。不是说微服务不好而是那一刻的复杂度和收益不匹配。简易原则给了我们一个明确的评判标准如果你需要用超过30分钟向一个新同事解释这个系统为什么这么设计那么这个设计大概率是复杂的而不一定是合理的。2. 2.10.1 职责边界的确定——不易视角下的架构实践这一小节的核心任务是回答在一个系统里什么应该是“不变”的答案落到具体实践就是职责边界。2.1 职责划分的本质是什么职责边界不是技术概念而是业务概念。它回答的是“这个系统到底在管理什么业务事实”。你可以把系统想象成一个公司每个部门要有清晰的职责否则就会出现三种情况要么没人做事要么重复做事要么大家互相甩锅。软件架构里的模块、服务、分层本质上就是给这个“公司”划定部门。DCI、DDD、六边形架构、整洁架构这些方法论各有各的分层方式但底层逻辑是一样的——把业务职责按稳定程度区分开稳定内聚不稳定外放。2.2 判断边界的实操方法本质识别五步法这里我根据自己的实践整理了一套判断“哪些职责应当被稳定隔离”的方法供你参考写出这个系统的核心业务动词。比如订单系统就是“下单、支付、发货、退款”内容系统就是“发布、审核、上下架、归档”。对每个动词追问它对应的业务事实是什么支付对应的是“资金所有权转移”发货对应的是“实物移交”退款对应的是“交易撤销”。判断这些业务事实是否会被频繁改变。比如“支付”背后可能牵涉支付渠道、对账逻辑、风控策略这些东西会经常变但它“资金所有权转移”这个事实不会变。把不变的事实沉淀为核心模型把会变的动作放到边界外层。对每个有争议的边界问一句如果这个边界错了我改起来是改一个模块还是要改整个调用链答案决定了边界的优先级。2.3 一个实战场景订单服务的边界之痛拿我之前负责的一个订单中心举例。早期团队把订单服务和支付服务做了一个非常细的拆分理论上是职责清晰但实际跑起来每次支付结果的回调都要跨服务分布式事务性能问题先不说排查链路异常的时候日志要跨三个系统捞。当时我们面临一个选择是把订单和支付合并成一个更大的服务还是继续维持拆分同时接受分布式事务的复杂度如果用“不易”的视角去看事情就很清楚订单和支付虽然业务上紧密关联但它们要应对的变化节奏不一样。订单规则跟着运营策略变支付接渠道跟着资金安全策略变。把它们拆开是为了让两边各自变化时互不拖累这是对的。问题是出在事务一致性方案上——我们不应该为了实现所谓的“最终一致”而引入过度复杂的基础设施而应该先审视业务流程本身看看是不是可以从上游减少不一致的可能性。最后我们做的是在订单侧合并了部分状态减少了对支付回调的强依赖但保留了订单和支付的职责边界。这个决定不是靠拍脑袋而是靠“不易”的判断——我们识别出了支付和订单各自的稳定业务事实并以此为准。3. 2.10.2 架构演进与风格选型——变易视角下的架构决策如果说职责边界是静态的那架构演进就是动态的部分。当一个系统活过两三年技术债、业务变化、组织调整会一起涌过来这时候最考验架构师的就是演进路线的选择。3.1 架构风格的本质对变化节奏的应答软件架构风格比如单体、SOA、微服务、事件驱动、插件化在外人看来是一堆技术名词但在“变易”视角下它们是不同的“变化应对策略”。单体架构适合业务早期因为业务还在探索期需求变化最快的不确定性是业务方向本身单体的高耦合反而有利于快速迭代和验证。微服务不是银弹它是在业务复杂度大到单体的“变易”已经传导到团队协作层面的时候才会显露出优势。这里必须提醒一个很常见的认知误区很多人选择微服务不是因为业务需要应对变化而是觉得微服务“高级”。这是完全把因果搞反了。架构风格的选择应该是对“变化在哪里发生、变化有多快、变化波及多大范围”的回答。从“变易”的视角出发我用一张表来对照常见的架构风格架构风格应对的变化类型变化传导路径适合阶段单体分层业务逻辑快速迭代函数调用业务探索期模块化单体模块内独立演进模块接口业务稳定期微服务服务间独立扩容、独立部署HTTP/RPC调用团队规模大、协作复杂期事件驱动业务状态异构同步消息事件跨系统、跨团队协作期每套风格都有它“变易”的适用范围没有哪个是绝对正确。3.2 演进节奏顺势而为这一节内容里有一个很关键的观点我用大白话翻译一下架构演进不要试图跨级跳跃而要顺着系统当前的承受力一点点走。这句话背后是有实际教训的。我认识一个创业公司CTO团队从8个人到30个人那年他决定直接把系统从单体改成微服务。理由很正当业务增长快、模块边界已经清晰了。但落地的时候发现团队里能写清楚RPC接口文档的人不超过5个运维能力更是几乎没有线上第一周就出了三次事故。这不是说微服务不对而是他没有遵循演进节奏。他缺了一个关键中间态——先把单体内模块边界划清楚模块间通过内部接口交互然后用一个类似契约测试的机制把接口稳定下来。等团队对“接口链路”这个概念有了手感再拆成物理服务就顺理成章了。用“变易”的话说系统的变化能力是需要时间生长出来的。你可以在架构上留“变化点”但不要试图立刻把变化点全部打开。3.3 如何为未来的“变易”做准备那么问题来了如果不做微服务怎么给未来留空间答案是识别“变化点”并把这些点隔离在稳定的边界之后。具体到实操有三个动作很值得做第一接口契约化。不论是不是微服务模块之间的接口都应当像“合同”一样明确禁止跨模块直接操作内部表或内部实现细节。第二数据归属明确。每个核心业务事实必须有一个唯一的owner。比如订单状态只能由订单服务修改其他系统只能通过接口读取。第三依赖方向可控。让依赖从“不稳定”指向“稳定”具体来说就是让易变的业务策略依赖稳定的领域模型而不是反过来。这三点做扎实之后哪怕你当前还是单体架构未来要拆微服务拆的是物理边界的壳逻辑边界早就已经就位了。4. 2.10.3 架构评估与决策——简易视角下的架构实践前两小节解决的是“怎么设计”的问题这一小节解决的是“怎么判断设计得好不好”的问题。在架构评审、方案选型的场景里这套“简易”视角的价值非常大。4.1 用“能否讲清楚”作为第一把尺我在做技术评审的时候最怕的就是那种复杂到要画五张架构图才能讲明白的方案。不是说复杂的方案一定是错的而是说当一个方案复杂到评审会上没人能完全搞懂的时候它很难被正确落地。“简易”原则给出的评估标准是这个架构是否降低了系统的整体理解成本如果一个方案虽然解决了一个局部痛点但让全局的理解成本上升了一大截那这个方案就是要警惕的。我通常会让方案提出者做一个测试找一个不参与这个项目的新同学让他根据架构文档在半小时内口述出系统的核心链路和数据流向。如果说不清楚那这个架构就是过度的。4.2 架构决策里舍比得重要这里还想分享一个容易被忽视的点架构决策的难度不在于“选什么”而在于“不选什么”。我在实际操作中看到过很多团队在架构选型时因为某个技术方案看起来很“完整”就全量采纳。比如为了做可靠消息引入了完整的MQ框架加事务消息、本地消息表、死信队列、消息追踪所有特性全开。结果业务量根本没到那个程度光是排队和运维成本就把小团队拖垮了。用“简易”的尺子去量这时候正确的决策就是“舍”——砍掉大部分用不上的功能只保留最核心的消息可靠投递能力。真正的架构功力在于敢于对“看上去很好”的东西说不。架构评审时我会要求方案里必须有一栏叫“我们决定不做什么”这个栏写得越诚实方案的成熟度就越高。4.3 一套可以复用的评审检查清单我把基于这一节整理的检查项放在这里平时评审架构方案可以直接对照打分该方案是否让每个模块的职责更清晰了还是更模糊了如果需求变了一处大概会影响多少个模块影响面在不在可控范围新引入的技术组件团队现有成员需要多久才能熟练运维方案在半年后和一年后分别需要付出多少维护成本你在方案里主动舍弃了什么舍弃得有没有依据这套问题没有标准答案但它能逼着架构师从“这个技术很牛”切换到“这个方案在我们的语境里是否合适”的思考轨道上。5. 系统侧案例对照从Linux IOMMU架构看“变易”与“简易”的平衡如果把视角稍微拉远一点这一节内容不仅适用于业务系统也适用于底层系统软件的分析。最近很多人讨论Linux系统IOMMU软件架构分析我看了之后发现这套“不易、变易、简易”的框架拿去拆解它几乎严丝合缝。IOMMU这个组件解决的核心问题是把设备访问内存的DMA能力纳入系统统一管控。从“不易”的视角看它的稳定业务事实是“设备要访问内存但访问必须受到权限和地址变换的约束”。这个约束不管设备驱动怎么变、虚拟化方案怎么变都是不会变的所以它就是IOMMU架构里的锚点。从“变易”的视角看IOMMU需要应对的变化非常频繁新设备不断出现虚拟化技术持续演进IOMMU页表的格式、缓存失效策略、和DMA重映射的协同方式都需要不断调整。所以Linux内核里IOMMU相关的代码会划分出多个层次比如核心API层、不同厂商的IOMMU驱动层、页表管理层各层之间通过稳定的接口隔离就是为了让“变易”的部分可以独立演进。从“简易”的视角看IOMMU的接口设计有一个很典型的特征它把底层的复杂细节尽量藏起来向上层提供一个相对统一且易于理解的DMA管理接口。用IOMMU的人不需要关心具体硬件怎么翻译地址就像用微服务的调用方不需要关心服务内部的实现细节一样。这就是“简易”的价值——把复杂度收拢把简单留给别人。所以我说这套“哲学驱动式软件架构法”不只是写业务代码的技术人员可以用做内核、做驱动、做中间件的人同样能从中获得一种分析框架。它不是具体的API而是一个帮你看清系统结构的方法论。6. 实践参考一套可直接用的架构审视自我提问清单讲完了原则、小节和实践案例最后给你一套非常实在的东西我在日常架构评估中会用到的自我提问清单。每当系统要改动、要评审、要重构的时候我都会过一遍这套问题收益非常大。6.1 “不易”维度的问题我能不能用三句话说清楚这个系统最核心的业务事实是什么这些核心业务事实是否有明确的模块归口有没有多个模块同时修改同一份事实的现状如果明天业务方要求改一个核心规则这个改动是被隔离在一个模块内还是会一路穿透到数据库系统里有没有被频繁改动、但本质并未变化的“伪易变”模块比如看起来每天都在改但改来改去都绕不开同样的核心逻辑。6.2 “变易”维度的问题最近半年系统的变化主要集中在哪些部分这些部分的架构设计是否刻意留出了变化空间你选择当前架构风格依据的是业务特性和团队能力还是因为它“流行”或者“看起来正规”当业务增长十倍时系统瓶颈会先出现在哪里这个瓶颈是可以通过扩容缓解还是必须重构代码结构才能解决当前架构里有没有“变化传导”设计得很差的地方比如一个底层模块的小改动导致上层十几个模块都要跟着改。6.3 “简易”维度的问题一个新入职的工程师需要多久才能真正理解系统并独立提交代码每次线上出故障排查链路靠的是“日志连猜带蒙”还是系统本身有清晰的错误边界和可观测性设计系统的复杂度和当前业务的价值是否匹配换句话说我们是不是在为想象中的未来支付今天的高额维护成本如果只能保留一项架构资产你希望它是文档、测试用例、还是模块设计文档为什么6.4 如何用这套清单做一次架构健康度自检你不一定需要等到大重构才用这套清单。我建议每季度花半天时间挑一个核心模块对照着清单过一遍把所有“不满意”的答案记录下来然后排优先级挑出两个下个季度可以改的点。这里面的关键不是把所有问题都消灭而是让架构问题保持在一个“可见、可控、可排序”的状态。绝大多数架构腐化都是从小问题被忽略开始的。等到问题大到必须重构时成本已经翻了不知道多少倍。7. 写在最后的一点个人体会我自己在实践这套方法的过程中最大的感受是它不是给你标准答案而是帮你在各种方案之间做出选择时多了一把稳定的尺子。你不需要把《易经》读得多深只需要理解“不易、变易、简易”这三个原则然后反复拿真实系统去对照。你可能会发现很多过去凭感觉做的判断——比如某个模块该不该拆、某个架构风格适不适合、某次重构的力度应该多大——用这三个维度一梳理思路会清晰非常多。最后再说一个实操上的心得这套方法最好用的方式不是一个人闷头想而是在做架构评审的会上拿这三个词作为讨论框架让团队成员分别从“哪些是该稳定的、哪些是应该接受变化的、哪些复杂度是应该被砍掉的”三个角度发言。你会发现讨论质量会明显不一样因为大家不再用个人喜好去争论技术选型而是回到了系统本身。如果你正在一个快速变化、又不得不在变化中保住底线的系统里做架构决策这套“基于易经的软件架构系统观”值得你花一个下午反复琢磨然后在你的下一个设计方案里试着用起来。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进