从一次线上事故说起
去年我们团队上线一个新功能,结果凌晨两点报警了——数据库连接池被打满。排查半天才发现,是两个服务用了完全不同的连接管理方式,一个用完即关,另一个却长期持有。问题根源不是技术选型,而是没有统一的开发规范。
别一上来就写文档
很多架构师拿到权限第一件事就是拉个 wiki 页面,列出十几条“必须遵守”的规则。结果没人看,更没人执行。真正有效的规范,得从痛点出发。比如上面那个连接池问题,就可以定一条:所有数据库客户端必须通过统一工厂创建,且默认开启连接超时。
让规范长在流程里
写在文档里的规则容易被忽略,但集成进 CI/CD 的检查很难绕过。我们在 GitLab 的流水线里加了一步静态扫描:
rules:
- if: $CI_COMMIT_BRANCH == "main"
script:
- pmd-check --rulefile=custom-rules.xml
- check-naming-convention --lang=java
只要提交代码不符合命名规范或存在高危调用,自动打回。几次之后,大家就知道哪些雷区碰不得。
留点弹性空间
曾经规定所有接口响应必须包装成统一格式,结果某个实时性要求极高的内部模块每次都要多花 2ms 做封装。后来改成:外部 API 强制包装,内部服务可申请豁免。关键是要有出口,不然大家宁愿偷偷违规也不走流程。
用案例代替条款
比起“禁止在循环中查询数据库”这种干巴巴的条文,直接贴一段出过问题的代码更有冲击力:
for (User user : userList) {
Address addr = addressDao.findByUserId(user.getId()); // 每次查一次 DB
user.setAddress(addr);
}
旁边标注:该逻辑在用户量上升后导致平均响应时间从 80ms 升至 1.2s。下次评审看到类似写法,自然会警惕。
定期翻旧账
每季度抽三个典型故障,反向推导是否需要补充或修改规范。有一次发现缓存击穿源于缺乏标准熔断策略,立刻补上一条:所有缓存读取必须配合降级开关,并在配置中心可视化控制。
让新人也能看懂
规范文档里夹一堆英文缩写和内部术语,新同事根本看不懂。现在每条规则后面都加一行“为什么”,比如:‘日志不允许打印密码字段’ —— 防止敏感信息泄露到 ELK 平台被非授权人员查看。
从样板代码开始
新建项目直接给一套脚手架,里面集成了日志、监控、异常处理的标准实现。新人复制过去就能跑,连依赖版本都锁好了。比反复强调‘要用 logback 而不是 System.out’管用得多。