ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

哲学驱动式软件架构:从易经三原则到嵌入式分层实践

哲学驱动式软件架构:从易经三原则到嵌入式分层实践 软件架构做了十几年我越来越确认一件事真正让架构分高下的往往不是某个具体模式用得好不好而是架构师看待系统的底层世界观。这几年我在团队内部推一套思路不跟风、不追新反而回头从《易经》里找架构的系统观效果出乎意料地稳。这篇文章就把这套哲学驱动式软件架构法的核心内容整理出来当前版本是2.4.15重点讲讲它是怎么从一套抽象观念落到真实工程决策上的。1. 先回答一个问题软件架构为什么需要哲学驱动1.1 架构决策的本质是价值取舍很多朋友一听哲学驱动式架构就觉得玄觉得不如来点K8s、微服务、领域驱动设计实在。但你可以回想一下自己最近一次架构评审会两个方案摆在桌上A方案数据一致性更强但吞吐量打折B方案性能好看但一致性需要最终补偿。两边技术都很硬选谁这时候你嘴上讲的是技术权衡骨子里其实是在回答一个哲学问题——这个系统的核心价值到底是什么稳定压倒一切还是体验优先一切软件架构的难点从来不是不会做恰恰是太多选择不知道怎么选。分层、微服务、事件驱动、插件化每个模式都是前人的经验封装但没有任何一本书能告诉你你手头这个系统、在这个阶段、这帮团队应该选哪个。这就是架构的决策困境**所有方法都对所以你只好把责任推给趋势、推给领导、推给业界最佳实践。**说到底这是缺失了决策赖以成立的系统观。1.2 从《易经》里找一套系统的元框架我在这套方法里引入《易经》不是因为它神秘而是因为它本质上是一部关于结构与变化的中国古代系统论著作。它讨论一个系统不管是你的人生、一场战争还是一座软件架构怎么由部分组成、这些部分怎么互动、怎么随时间演变、怎么在某个特定位置上发挥恰当的作用。这些概念拿来映射软件架构几乎是严丝合缝的整体性一个软件系统大于模块之和模块之间的连接方式往往比模块本身更重要。关联性没有哪个模块可以独立存在改动永远有涟漪效应。动态性系统不是静态蓝图是可生长的有机体。情境性没有绝对正确的架构只有在这个时间点、这个位置上恰当的结构。这四个特征覆盖了架构师每天都在处理的问题。哲学驱动不是要你在写代码前先卜一卦而是给决策者一个在技术之上、用于判断的元框架当所有技术方案都貌似有理时你靠什么站住脚这就回到了一句老话架构师的能力一半在技术一半在选择技术的依据。2.4.15版本内我反复强调一句话*架构方案永远不是最先进的胜出而是最与系统当下状态匹配的胜出。*这一条认知后续几乎所有原则都从它派生出来。2. 阴阳、变易、时位三大核心观念落到架构上的投影《易经》观念很多真正进入架构决策、能直接使用的我这些年提炼为三项。2.1 阴阳架构里的对立统一与互根互生阴阳不是简单的好坏两分它的精义是对立、互根、消长、转化。同一系统的两种特性既互相制约又互相依存某一边涨到极限就会向另一边转化。对照软件架构最典型的就是稳定和变化稳定阴系统要可靠、可控、可预测这要求接口收敛、依赖规整、变更谨慎。变化阳系统要扩展、演进、响应需求这要求模块解耦、接口灵活、架构留有余地。很多架构冲突都能归到这组阴阳上。单体架构的团队天天被需求追着跑开始拆微服务拆完微服务分布式复杂度爆炸又想合并回模块化单体。这就是消长与转化的真实写照。模块化单体不是又回到原点而是阴阳在更高层次上的新的平衡。我把这个观念转成一套架构四象限分析法放在2.4.15版里作为第一个决策工具给每个候选架构方案按稳定性贡献和演进性贡献打分再按维护性成本和认知负载做修正。打分不是为了求一个静态最优解而是直观地看到任何一种架构选择都是同时维持着稳定与变化这对矛盾。一个好架构不是消灭矛盾而是给这对矛盾设计好缓冲带和转化通道。具体手段就是防腐层、适配器、版本化接口、事件契约这类中间结构它们的作用本质上是调节阴阳消长的节流阀。2.2 变易承认架构是一个演化过程而不是一张静态图纸《易经》讲穷则变变则通通则久这在软件工程里的翻译就一句话**架构一定会死好的架构是允许自己体面地死掉的架构。**有多少系统死在当初架构定的太死上面数据模型改了要动20张表流程变了要改状态机新业务形态来了连边界都找不到。根本原因就是架构被当成山一样定死了没有给它留变动的接口。所以这套方法里有一条硬性规定每次架构设计交付必须附带一个变易清单明确回答四个问题最容易变的部分是什么→ 必须做接口抽象禁止直接暴露内部实现。什么部分我们希望它永远别变→ 核心领域逻辑要减小外部依赖重点测试锁定。变了以后牵连面多大→ 画出影响范围图变更成本一目了然。用什么机制承载变化→ 配置开关、插件点、特性分支、事件扩展点还是多版本并存这条规则直接改变了团队做事方式过去大家做架构是把结构画漂亮现在做架构是把变化的通道预留好。一个模块好不好不再只看它的内部清晰度还看它能否在不变更调用方的前提下完成演化。变易观用得好的系统就像一个有新陈代谢的活体局部在替换整体骨架依然稳定。2.3 时位架构的正确性取决于时机和位置这是整副框架里我认为最锋利的一个观念。一个爻放在不同卦位含义完全不同一种架构放在不同阶段的企业里效果也完全不同。**没有好架构只有适位的架构没有最好的时机只有当下的匹配度。**这就是时与位。放到工程里位指系统在全局中的角色以及模块在系统中的层次和职责。你做一个订单中心和一个数据报表系统对事务一致性的要求注定完全不同你在网关层和业务核心层写同样的判断逻辑本质上就是位摆错了。时指系统生命周期和团队成熟度系统阶段合适架构倾向不太合适的倾向0到1验证期模块化单体、快速交付、容忍技术债大张旗鼓微服务化、追求完美分层1到100扩张期服务拆分、团队边界对齐、明确接口契约过度抽象、为不确定的未来过度设计成熟稳定期平台化、标准化、性能优化、安全加固频繁重构、追逐架构时尚衰退或转型期防腐层隔离旧系统、渐进式替换大规模推倒重来成本失控风险极高这套表帮我们抵挡了很多为拆而拆的冲动。之前有团队非要把系统微服务化理由是业界都这么干。对照表格一问你现在两个服务、八个开发、业务模型都没完全跑通微服务带来的好处你一个都吃不到分布式事务的苦倒先吃全套。于是大家冷静下来先把模块边界划清楚、把数据所有权理顺等到业务量和管理复杂度真的上来再拆不迟。这就是时。对一个架构师来说时位观念最大的用处是拒绝被绝对标准绑架。你在评审时可以说这个方案在别的场景是对的但在这里不适位这句话比我更喜欢XX架构有说服力得多。3. 系统观落地五条可执行的架构操作原则有了观念下一步就是翻译成操作手势。2.4.15版把观念凝成五条原则每条都能在代码评审和架构评审里直接提问、验证。3.1 整体先于部分先画影响圈再谈模块划分很多架构方案上来就从我打算拆成用户服务、订单服务、支付服务开始这是从部分出发的设计。系统观的做法相反**先界定系统的核心目标再画清楚系统与外部环境的边界和交互然后看内部为了维持这个整体行为需要哪些结构和连接。**顺序反了拆出来的模块再漂亮也是拼贴不是系统。我在评审时有个固定动作请方案讲解人先画系统上下文图标出使用者、上下游、外部依赖再画核心数据流最后才看内部模块图。凡是跳过前两步直接讲内部结构的方案我都会打回去。这不是教条而是因为整体目标一旦没定明白模块边界的合理性根本无从评价。你们争这个功能该放A服务还是B服务本质上是对整体是什么没达成共识却在细节层面吵架。3.2 以衡代优把最优解从字典里删掉受算法思维影响我们总下意识地想找最优架构。实际情况是**在真实约束下可选的架构方案里根本没有一个在所有维度都领先的最优解只有综合得分最高的平衡解。**这个观念直接来自易经的中道思想重点不是求某一方面极致而是让整体处在一个可长久的均衡态。落地为工程实践时我们设计了一张架构决策平衡计分卡每次重大架构选型都过一遍业务匹配度方案是否贴合核心业务流程的走向团队可维护性现有团队能否在未来6到12个月内稳定理解并演进这套架构运行成本资源、部署、监控、排障的长期开销是否可接受演进空间为未来最重要的两三个变化是否预留了通道风险暴露最大技术风险是什么是否有缓解预案评分不是为了选第一名的方案而是把隐含权衡摊到桌面上让决策者看到每个选项的真实代价。这个动作做下来团队里我就要用XX的争论明显变少因为大家都知道最后要过的是整体平衡不是单一偏好。3.3 留白设计里要给未知需求留下可生长空间易经卦象之间讲究当位和不当位但在结构上常常留出虚位以应变化。软件架构一个最常见的灾难是精确过度把所有现在能想到的情况都建模成最强类型的结构把每条路径都钉得死死的结果需求一变整面墙都得拆。留白原则翻译成架构语言包括这些具体动作数据库字段核心表的扩展字段不要一开始就建模成强类型列预留在JSON列或侧表中等到模式稳定了再提拔为正式列事件协议消息体里预留一个metadata扩展区域避免每个字段变化都牵动所有消费者工作流引擎核心流程固定非核心步骤以扩展点方式开放不把所有分支都写死在编排里团队边界模块间不强制从一开始就把所有交互接口定义完毕允许先松散协作待模式清晰后收敛为正式契约。有些工程师会觉得留白是偷懒实际正好相反**留白是对不确定性的成本控制。**你省下的不是当下的设计工作量而是未来变更时的连锁爆炸成本。留白的关键是别留成不提需求就无限期拖着的模糊地带要给它明确的收敛条件。3.4 当位让每个模块待在该待的位置上位这个概念再往下走就是模块职责的清晰性。在一个系统里每层、每个模块都有自己的位——它在整体中的角色。当位的模块责任单一、依赖方向明确、可替换性高失位的模块戏份模糊、到处横跨、改哪里都碰到它。我判断一个模块是否当位就问三个问题你能不能用一句话说出这个模块在系统里的角色如果说不清它一定是失位的。它依赖的方向对不对上层依赖抽象、依赖下层接口是正常方向下层反向依赖上层报警。替换它需要动多少外围真正当位的模块替换代价应该基本可控。这套判断在微服务和模块划分里超级实用。经常有人说我按领域划分了服务结果一画依赖图还是绕成一团——因为领域边界没对齐位的逻辑。每当遇到这种纠缠我都建议大家退回到一句话原则让模块之间靠契约协作不靠彼此的补丁维持。3.5 复卦思维把反馈循环作为一等架构公民《易经》里的复讲的是循环往复、物极必反的节奏感放到架构里它的化身就是反馈闭环。一定要把反馈机制当成架构的一部分来设计而不是事后补监控。以前做系统监控告警是运维同学顺手配的日志想打就打链路追踪大部分是服务之间靠查日志拼。后来我们把反馈循环提升成架构设计的强制项每个服务必须要回答清楚我的健康怎么度量、我的故障怎么发现、我的性能怎么反馈、我的变更怎么验证。落地下来就是标准的可观测性三件套结构化日志、核心指标埋点、链路追踪再加一个变更前必须有回滚预案的红线。这里要特别提醒反馈不是只有技术监控还包括业务反馈。你做架构时能不能快速拿到这个功能上线后用户到底用没用、转化怎么样的数据**如果系统里没有为业务反馈准备的埋点通道说明架构的反馈维度是残缺的。**反馈闭环让系统不盲动也让我们做调整时有依据这是复字在工程里最实在的兑现。4. 用这套系统观推演一遍嵌入式系统分层软件架构前面讲原则偏抽象我们拿一个大家最常搜的嵌入式系统分层软件架构来走一遍完整推演看这套系统观是怎么把散落的原则拧成一股绳的。嵌入式系统因为资源受限、硬件多样性、安全要求高天然是分层架构的典型场景。4.1 嵌入式分层结构的位与时一个典型的嵌入式分层长这样下面给出一个常见的五层划分示例层次和命名可以按项目调整核心是每一层的位清晰硬件抽象层HAL位在向上屏蔽硬件差异。MCU换了、寄存器变了、引脚变了上层不感知。这里的关键设计是不许有业务逻辑只做硬件能力的最小化封装。板级支持包BSP位在硬件初始化与基础服务。时钟、中断、内存布局的初始化都在这一层它是启动最早的代码也是移植工作量最大的部分。操作系统抽象层OSAL位在隔离RTOS差异。任务创建、信号量、消息队列、时间管理统一成一个薄接口让应用层可以跨RTOS迁移。中间件与服务层位在提供可复用的业务无关服务。通信协议栈、文件系统、OTA升级管理、日志服务都被中间件承接。应用层位在承接具体产品业务。业务逻辑、产品策略、用户交互。这一层要求的是方便变更、单元可测因为业务需求最活跃。分层架构为什么能在嵌入式里长期站住脚用系统观的三个词解释整体目标软硬件解耦、可移植、可维护、结构连接层间依赖单向向下各层通过接口协作、变化承载硬件换代改下层业务变化改上层互不牵连。这不是哪一种模式碰巧流行而是它精准呼应了嵌入式系统的整体演化需求。4.2 分层不是目的失位才是最常见的病分层架构名声好但很多人分层分成了形式主义。最常见的失位问题有三个**第一个跨层调用。**业务层绕过中间件直接操作HAL的寄存器。短期图省事长期硬件一变业务代码跟着翻车。这是最典型的当位意识缺失。我们的硬规矩是向上依赖只允许逐层引用跨层必须走抽象接口否则评审一票否决。第二个模糊层内边界。中间件层变成了垃圾场协议栈、算法库、加密库、UI库全塞进来。表面看也是分层内里乱成一锅粥。用系统观的办法往下再细分把中间件层内部按职责拆成更小的位通信域、存储域、安全域、诊断域每个域内的模块依然满足高内聚低耦合。**第三个把分层变成层层转发。**为了守不能跨层的规矩每一层都只做透传代码里一堆无意义的转发函数。这种教条化恰恰违反了变易精神。正确态度是**分层是为了控制依赖不是为了增加执行的中间环节。**如果某层对请求没有实际加工或保护作用合并相邻层是更健康的选择。4.3 分层设计中的阴阳取舍隔离力度与资源消耗嵌入式系统里资源贵而分层是有成本的结构。每次跨层调用都是一次函数跳转和上下文切换每加一个抽象接口都意味着ROM和RAM的开销。这就是架构里的阴阳**隔离性稳定、清晰与资源效率轻巧、高速**是天然对立的。举一个真实例子某个物联网网关项目最初设备驱动接口设计成万能类型一个ReadDevice(channel, buf, len)加一个设备类型参数期望适配几十种传感器。这个接口调用开销小但每加一种传感器switch-case就膨胀一次驱动代码越来越像贴满膏药的旧账本。后来我们为高频传感器单独开了带类型的安全接口保留了低频场景的通用接口Rom和Ram只增加了不到2%却让代码清晰度大幅提升。这就是在稳定与效率之间找均衡的度。所以做嵌入式分层时必须有这张表在心里设计取向带来的收益付出的成本适用信号更多抽象层替换性好、可测性强资源占用高、执行路径长硬件平台多、产品线长更薄更直接性能好、简洁硬件变异适应差单一硬件、极致性能要求接口收敛统一维护成本低类型多样场景需要泛化设计外设种类多、版本滚动频繁每次做分层我都会让大家先回答我们到底为了什么分层再谈分层分几层、接口怎么定。没有这个前提所有分层讨论都会变成技术偏好之争而不是系统结构之争。5. 2.4.15版本里沉淀下来的实战经验版本编号走到2.4.15每一轮的迭代都是被真实项目教训推着走的。这里把最实用的经验写出来算是这一版里我最想划重点的部分。5.1 让架构评审从看图说话变成系统观检查清单过去架构评审的典型场景是讲解人放一张架构图大家凭直觉提意见谁气场强听谁的。后来我把上面这些观念压成一张评审检查清单每次评审照着过一遍。核心条目包括系统边界和上下文图画清楚了吗整体目标与架构方案之间有没有明确因果关系模块划分是按位切的还是按组织结构、技术栈、历史包袱切的依赖方向是否清晰可控有没有循环依赖或者反向依赖变化最大的板块有没有预留扩展通道变化最小的板块有没有过度设计跨模块交互是否有明确的契约和数据流而不是靠口头约定稳定性与演进性之间的平衡在哪成本是多少谁为这个平衡负责架构反馈回路监控、日志、链路、指标、回滚预案是否齐备这张清单不解决评审气氛的问题但极大提高了评审效率。因为大家开始用同一套语言讨论问题意见再也不是感受流而是针对系统结构的判断。边界模糊依赖倒挂变易通道缺失说完方案需要改的地方已经很明确了。5.2 架构演进要有变卦的勇气也要有复卦的节制软件系统跑几年后总会有从这座山头看那座山头高的冲动。有的架构师喜欢频繁把新概念引入老系统觉得不重构就没有技术成就感。2.4.15版里专门沉淀了一条关于重构的纪律我称之为变卦三问当前系统的痛是否已经真实地、频繁地、用数据证明存在如果只是感觉代码乱看别人都在拆不算数。变后的架构是否显著改善这个真实的痛你换架构之前先把痛点指标量化出来改完对比不然重构就变成了大型行为艺术。代价是否在团队能承受的范围包括时间、资源、风险、业务停滞成本。三条都满足果断变只满足一条冷静再等等。这几个问题看着简单真到评审现场能挡住一大半冲动型重构。与此同时还要理解复卦的节制不是所有磨损结构都要推倒很多通过局部加固就能解决。物极必反不等于天天返工一个系统走到极致复杂的时候要敢于简化回退但简化回退的前提一定是复杂度已经在真实地拖慢交付而不是因为觉得不够优雅。5.3 架构文档最值钱的一张图依赖与变更影响图很多团队的架构文档越写越厚画满了部署图、组件图、时序图但很少回答那个最要命的问题**改动一个模块影响面到底在哪**我建议每个架构师在文档里必须画一张依赖与变更影响图把核心模块的上下游依赖、共享数据、同步调用关系画清楚一眼能看到牵一发而动全身的关键点。这张图的价值在日常排需求任务时立即显现拿到需求先查影响图圈出受影响的模块预估工作量心里有了底接口谈判也有底气。对架构演进来说它还能告诉你哪些节点是高风险变更点单独为它们设计防护措施。文档是用来辅助决策的不是用来充门面的这一点被很多人忘了。5.4 别把架构演进搞成一次性大爆炸我见过不少团队立志要在一个黄金窗口期把整个系统从单体重构到服务化。结果窗口期一拖再拖技术债越滚越多。用变易观来看**架构演化应该是渐卦——循序渐进的变化不是革卦式的推倒重来。**具体做法是先把最痛的一块边界划出来把它从系统里模块化剥离定义好新旧两侧的接口用防腐层隔离让新旧结构同时运行一段时间在过程中持续验证稳定性再决定是否扩大剥离范围不要等重构彻底完成才交付价值每次切分都要产生可感知的业务收益或团队收益。这么做的效率反而更高因为风险被摊薄到每一步里出问题能立刻退回而不是整个项目绑在一场豪赌上。这也是哲学驱动式软件架构法最讲求实用的一项体现观念可以很古老做法必须很现代、很工程化。6. 这套框架的边界什么时候别拿《易经》说事最后必须泼一盆冷水。哲学驱动的架构法虽然好用但它有明确的能力边界用过头就是灾难。我把这几年踩过的界线列清楚。6.1 它给的是判断框架不是技术答案有人问我那你说我们这个系统该用K8s还是ECS我的回答是这套框架不会替你选容器编排平台它帮助的是厘清你所在的是存量系统迁移场景还是绿地增量场景、团队有多少运维能力、故障容忍度多少然后你用这些判断条件去匹配技术方案。哲学驱动的核心是让你在信息不全的情况下依然能做出前后一致、理由充分的决策。6.2 别把它当作论证工具来给自己的偏好贴金任何一个架构方案都能从阴阳平衡当位变易通道里找到解释。所以这套方法最危险的用法是已经决定了方案再回头编一套系统观理由。这算自欺欺人。**框架必须用在决策之前不是在决策之后做包装。**每次评审我都要求把系统观判断写在方案选择的理由里而且要写明我的方案牺牲了哪一方面。不牺牲的方案都是骗人的写不出来说明压根没想清楚。6.3 紧急时刻直接跳过哲学讨论系统在线上故障、用户大面积报障、老板在会议室瞪着你的时候不要讲哲学先处理故障、修复问题、保证恢复。救火和架构设计是两个场景**救火要的是最快恢复预案架构设计求的是长期平衡。**这套方法的应用场景是月度架构评审、新项目设计、重大技术选型不是生产环境的故障响应当中。6.4 别把古老智慧当教条要当思维脚手架我一直强调《易经》提供的是启发性的思维框架不是放之四海而皆准的公式。同样的思想也能从控制论、系统动力学、复杂性科学里得到印证。我的建议是**把阴阳理解成稳定与变化把变易理解成演化把时位理解成嵌入式系统的生命周期约束**把它们当脚手架搭完就拆最终留下来的是一整套你自己的架构决策习惯。2.4.15版本值不值得你用我的标准就一个看你下次参加架构评审时是继续凭感觉、凭资历、凭谁的嗓门大去说服别人还是能一句话说清楚这个方案在这个系统、这个时期、这个位置上为什么是平衡的。如果是后者这套方法论就起作用了甚至你用不用《易经》这个词都不重要。
返回列表