首页 / m.itcdj.com / 正文

代码评审中的架构一致性检查 别让零散代码拆了系统的台

上周帮一个做电商的朋友复盘故障,根因说出来可笑到离谱——三个迭代周期里,前端组为了赶活动,把本该走服务层鉴权的接口,直接在页面层调了内部的库存查询服务。没人觉得这是大事。能跑就行。直到第三方的恶意爬虫顺着这个没鉴权的口子,把全平台的库存数爬了个干净,运营团队盯着后台跳个不停的异常告警,花了整整四个小时才把所有的爬取接口临时封掉。

别把架构检查当成过流程的橡皮图章

说真的,我每次开代码评审会碰到这种情况,都要叹口气。大家都盯着代码的语法细节抠来抠去,觉得把变量名起得规范了,把注释写全了,把单元测试覆盖率凑够了,就是负责任的评审。可偏偏最影响系统长期稳定性的架构边界问题,成了评审桌上没人愿意碰的软柿子。大部分团队的评审清单里,架构相关的检查项占比连10%都不到。不是大家不知道架构一致性重要,是怕提了就得罪人——毕竟谁也不想当那个挑刺的人,翻着半年前的架构文档,说你现在写的代码不符合当初的设计。

毕竟大家都是赶进度的人。多一事不如少一事。只要当前的代码能满足业务需求,能顺利合并到主分支,谁愿意为了一个“可能以后会出问题”的架构偏差,跟同事掰扯半小时?

代码评审会议现场 工程师对着屏幕标注架构偏差

这种心态下,评审慢慢就变了味。成了走流程的橡皮图章。你批我的代码,我过你的提交,大家客客气气,绝口不提架构上的跑偏。直到某一天系统撑不住了,翻历史提交记录才发现,原来早在好几个迭代之前,就有人悄悄绕开了所有约定的边界,把代码写得东一块西一块,最后拼成了谁也不敢动的大泥球。

哪些偏差是必须当场揪出来的硬问题

当然我也不是说,所有和最初架构文档不一样的地方,都是错的。架构本来就是跟着业务演进来的,要是死抱着半年前的文档当金科玉律,那才是真的僵化。判断偏差是不是问题的核心标准,从来不是“和文档是不是一模一样”,而是“这个改动会不会让后续的修改成本指数级上升”。

比如几类问题,是必须在评审的时候当场指出来的。第一类是绕开了约定的分层边界:本来应该在服务层处理的鉴权、参数校验逻辑,散落在各个前端页面或者Controller层里;本来应该封装在公共组件里的能力,被每个业务模块抄了一遍代码。第二类是打破了统一的调用规则:本来所有跨服务的请求都要走统一的网关做限流、熔断、日志埋点,结果有人在业务代码里硬写了个HTTP地址,直接调隔壁服务的接口,既没有限流也没有重试。第三类是偷偷引入了和现有技术栈不兼容的依赖:比如团队本来统一用MySQL做持久化,有人为了图方便,在业务模块里引了个SQLite的本地数据库存临时数据,后续要排查问题的时候,连统一的监控都接不上。

系统分层架构边界校验示意图
系统分层架构边界校验示意图

之前见过一个团队,大家都嫌每次评审架构问题太费时间,把所有架构检查的环节都砍了。结果过了两个大版本,要给全平台加统一的操作审计功能,翻遍代码库才发现,有快20%的用户操作逻辑根本没走统一的审计SDK,散落在各个业务分支里。光是把这些零散的逻辑找出来、补上审计埋点,就花了整整一个迭代的时间。算下来,当初每次评审多花5分钟核对的事,最后要花几十倍的时间补窟窿。

别搞成人人自危的架构审判

不过话说回来,很多团队也确实把架构一致性检查搞歪了。专门找个架构师当裁判,只要看到代码和文档对不上,不管实际场景是什么,直接打回。完全不管开发是为了适配特殊的业务场景,才做的灵活调整。

有个朋友跟我吐槽,他们团队的规则死得很:所有的缓存操作必须用团队统一封装的客户端,连参数都不能自己改。结果有个开发为了应对大促的热点key,在代码里加了一层本地缓存的兜底逻辑,就因为没用那个统一封装的客户端,被架构师直接打回。硬把本地缓存的逻辑拆了之后,大促当天热点key把Redis集群打挂了,整个库存系统卡了20分钟,损失谁来担?

真正有效的检查,从来不是要求所有人100%复刻最初的架构设计,而是要让每一个架构上的偏差,都有明确的记录、有对应的评估、有后续的演进方案。不是要把开发的手脚捆死,是要让大家知道,我们当初定这些架构规则,到底是为了解决什么问题。不是为了卡流程,是为了避免大家在不知不觉中,把系统拆得七零八落,最后谁也维护不动。

我见过太多团队的架构文档,写完就扔在共享文档的角落里,半年没人更新,最后成了没人认的废纸。代码评审中的架构一致性检查,本质上根本不是要把人卡死在最初的设计里。是给整个系统留个锚点。知道大家走了多远,哪些地方走岔了,哪些地方其实可以顺着新的路径,把整个系统调得更顺。

别等系统塌了才想起来。