系统已经有网关、注册中心和多个服务,但修改一个业务字段,仍然需要召集所有负责人一起上线;一个下游接口变慢,上游多个服务都开始超时。如果这类现象持续出现,值得重新检查服务边界,而不是继续增加服务数量。
一、先看是否具有真正的独立性
“分布式单体”常用来描述这样的系统:代码与运行进程已经分散,变更和运行却仍然高度耦合。它不是仅凭服务数量就能判断的标签。共享部署窗口有时是组织流程要求,需要区分技术上不能独立发布,还是流程上尚未允许。
可以抽取最近几次需求,列出涉及的服务、数据库和发布批次。如果多个服务反复随同一种业务变化而修改,检查它们是否被过早拆开,或是否共享了不稳定的内部实现。
二、重点检查三类依赖
| 依赖类型 | 值得关注的现象 | 需要核实的问题 |
|---|---|---|
| 变更依赖 | 一个字段变更引起多个服务同步升级 | 接口是否暴露内部数据结构,是否允许版本兼容? |
| 运行依赖 | 一个用户请求串行调用很多服务 | 哪些结果必须同步取得,失败后是否有可接受的处理路径? |
| 数据依赖 | 多个服务直接修改同一组业务表 | 谁负责数据规则,谁有权修改,如何保持一致性? |
三、先用证据画依赖图
架构图应结合实际调用、代码引用与数据库访问记录,而不只是设计文档里的方框。为每条关系标明同步或异步、调用频率、超时设置、业务影响和负责人。重点观察关键流程,以及故障中出现的重试和级联等待。
微软对频繁细粒度 I/O 的反模式分析指出,大量小请求可能带来额外开销。判断服务交互是否过于频繁,应结合调用数据,而不是简单以“远程调用次数越少越好”为唯一目标。参见Chatty I/O 反模式说明。
四、改善顺序不一定是继续拆分
- 稳定契约:减少调用方对内部字段和处理顺序的依赖,明确兼容周期。
- 确定数据所有者:梳理跨服务写入,逐步通过清晰的接口或事件表达协作。
- 减少不必要的同步链:对业务允许延后的工作评估异步方式,并同时设计幂等、重试与异常处理。
- 重新评估边界:如果两部分始终共同变化,合并或调整边界也应进入候选方案。
消息队列不能自动消除耦合。如果调用方发送消息后仍然一直等待结果,或者多个消费者依赖严格的隐含顺序,耦合可能只是转移到了另一条链路上。
五、如何判断治理有效?
选择一个近期确实发生过的变更,在调整后验证它能否只修改必要的服务;演练一个依赖失败,检查影响范围是否符合预期;让团队独立完成发布,确认没有遗漏的人工同步步骤。
如果你已有 .NET 微服务,但发布和故障仍然相互牵制,可以先做一次架构依赖评估。交付重点应是关键耦合点、边界调整建议和可验证的治理顺序,而不只是换一套组件。