公司新上线了一个电商项目,后端团队五个人分工明确:两个负责用户和订单模块,一个搞支付对接,另外两个维护商品和库存服务。听起来挺合理,可上线前两周,问题开始冒头。
接口对不上,最常见也最头疼
订单服务要查用户信息,调用方说“我按文档传的 userId”,提供方却说“我们这边接收的是 userCode”。一查才发现,Swagger 文档更新了三次,没人同步给下游。最后靠在群里挨个 @ 才对上字段。从那以后,团队加了一条规矩:接口变更必须发邮件 + 钉钉提醒,还得在 Git 提交里写明变更点。
代码风格不统一,读起来像猜谜
有人喜欢把逻辑塞进 Controller,有人坚持 Service 层必须纯净。一次排查库存超卖问题,三个人看同一段代码,愣是花了半小时才理清执行路径。后来团队引入了 ESLint 和 Prettier,配合 CI 流水线做检查,提交代码时格式不对直接被拒。虽然开始有人嫌烦,但两个月后,新人接手项目明显顺畅多了。
本地跑得好好的,一上环境就崩
开发小李在本地测试支付回调一切正常,可预发布环境总是收不到通知。折腾半天才发现,本地用的是公网测试地址,而 Docker 容器里的配置还指向内部 Mock 服务。团队随后上了 Config Center,所有环境配置集中管理,不同环境自动加载对应参数,再也没出现过“我本地没问题”这类甩锅台词。
日志乱成一团,出事只能干瞪眼
某次大促期间订单突增,系统开始报错。翻日志时发现,有人打 info 级别输出整个请求体,有人把异常堆栈吃了也不打印。最后靠 ELK 把日志捞出来,手动拼接上下文才定位到是数据库连接池耗尽。现在团队规范了日志模板:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</configuration>同时要求关键路径必须记录 traceId,方便链路追踪。
沟通不能只靠文档
光有 Confluence 不够。每周固定半小时“技术碰头会”,不讲 PPT,就聊最近遇到的坑和下周可能的冲突。比如支付组提前说要升级 SDK,订单组就能早点评估兼容性。这种非正式交流反而减少了后期扯皮。
后端协作不像写算法题,没有标准答案。大家水平都不差,真正卡住项目的,往往是那些没对齐的细节。把流程踩顺了,人和人之间的衔接比代码还重要。