05 · 架构 · 模块与一致性
仓库、财务和表格不能各记一笔库存
资深架构师决定模块边界和失败时以谁为准。资深在于有权退回「先临时写一下」;跨系统身份不归他,交给解决方案架构师。
资深架构师拆的是责任,不是技术名词
解决方案顾问已经用留、建、读、写定了系统级边界。资深架构师把它落成模块:库存、单据、主数据、权限、集成、打印,各自拥有什么数据,允许别的模块怎样调用。岗位特点是对「先临时写一下」过敏。临时写入会变成第二本账。他要在开发开始前写清:库存数量只由库存模块改,单据模块只能提交意图;主数据只读;集成模块不能直接改库存,只能投递已确认的业务事件。
他也规定一致性,而不是把所有调用都做成同步。同步看起来简单,金蝶一超时,收货页面就转圈,仓管会再点一次。架构上收货本地先完成到「待回写」,集成按事件重试。这不是实现细节可有可无,这是模块边界。谁把回写写进收货事务里,谁就把外部系统的故障引进了仓库操作。
一张架构说明里必须回答的失败
达希要求架构说明回答五个失败,而不是只画成功时的箭头。重复提交会不会记两笔。外部超时后本地是什么状态。主数据不存在时是拒绝还是自动创建。两个模块同时改同一库存时谁赢。消息重复投递时下游如何识别。答不出的模块不能开工。技术选型,例如用队列还是定时拉,放在这些答案之后。选型如果先于答案,团队会为了用上某个组件而改变业务失败的含义。
资深架构师不写每个接口的字段表,那是后端和集成工程师的工作。他评审字段表是否越过了边界,例如前端传来的库存余额被直接覆盖。越过的设计退回,即使它能让演示变快。跨项目复用的模块约定也由他收口,不让每个项目再发明一套库存写入。
WMS、ERP 和 Excel 同时改库存的那次
配送项目里,仓库用新系统收货,财务在金蝶看库存,计划员仍用 Excel 算可售。三边每晚对不上。资深架构师没有接受「做个对账报表」作为解法。对账报表只是把三本账展示在一起。他规定:可售库存的主人是新系统里的库存模块;金蝶接收的是已关闭单据的汇总,不反向改仓库数量;Excel 取消录入资格,改为从库存模块导出,导出文件带时间和仓库,禁止再导回。计划员如果发现数错,走差异单,不改表格。
实现上,收货、上架、差异关闭都是库存模块的命令。集成只消费「单据已关闭」事件。Excel 宏被实施从计划员电脑移除。上线后仍有一天金蝶的数慢了四个小时,因为队列堵住,但仓库可售没有被金蝶回写覆盖。这是架构要保证的方向:慢可以,反向覆盖不可以。
模块边界交给技术负责人在代码评审里执行。跨系统的身份和账号不在这一页里解决,交给解决方案架构师。
架构说明还要写清读模型。列表页可以冗余状态,方便查询,但冗余只能由事件更新,不能让列表自己成为可修改的第二本账。有人在待收货列表上直接改数量并保存,这种设计会被退回。查询可以快,命令必须走库存模块。快如果以牺牲单一写入为代价,对账成本会在月结时一次性付清。
他用一张真实的失败单据做架构评审,而不是只用框图。单据上能指出每一跳落在哪个模块、哪一跳允许重试。指不出的箭头,从文档里删掉。删掉之后如果业务路径断了,说明模块还没拆对,继续拆,不先写代码。