跳至正文
← 全部技术洞察

TECHNICAL INSIGHTS / 技术洞察

服务拆了,发布还要一起上?警惕 .NET 系统变成“分布式单体”

系统已经有网关、注册中心和多个服务,但修改一个业务字段,仍然需要召集所有负责人一起上线;一个下游接口变慢,上游多个服务都开始超时。如果这类现象持续出现,值得重新检查服务边界,而不是继续增加服务数量。

一、先看是否具有真正的独立性

“分布式单体”常用来描述这样的系统:代码与运行进程已经分散,变更和运行却仍然高度耦合。它不是仅凭服务数量就能判断的标签。共享部署窗口有时是组织流程要求,需要区分技术上不能独立发布,还是流程上尚未允许。

可以抽取最近几次需求,列出涉及的服务、数据库和发布批次。如果多个服务反复随同一种业务变化而修改,检查它们是否被过早拆开,或是否共享了不稳定的内部实现。

二、重点检查三类依赖

依赖类型值得关注的现象需要核实的问题
变更依赖一个字段变更引起多个服务同步升级接口是否暴露内部数据结构,是否允许版本兼容?
运行依赖一个用户请求串行调用很多服务哪些结果必须同步取得,失败后是否有可接受的处理路径?
数据依赖多个服务直接修改同一组业务表谁负责数据规则,谁有权修改,如何保持一致性?

三、先用证据画依赖图

架构图应结合实际调用、代码引用与数据库访问记录,而不只是设计文档里的方框。为每条关系标明同步或异步、调用频率、超时设置、业务影响和负责人。重点观察关键流程,以及故障中出现的重试和级联等待。

微软对频繁细粒度 I/O 的反模式分析指出,大量小请求可能带来额外开销。判断服务交互是否过于频繁,应结合调用数据,而不是简单以“远程调用次数越少越好”为唯一目标。参见Chatty I/O 反模式说明。

四、改善顺序不一定是继续拆分

  1. 稳定契约:减少调用方对内部字段和处理顺序的依赖,明确兼容周期。
  2. 确定数据所有者:梳理跨服务写入,逐步通过清晰的接口或事件表达协作。
  3. 减少不必要的同步链:对业务允许延后的工作评估异步方式,并同时设计幂等、重试与异常处理。
  4. 重新评估边界:如果两部分始终共同变化,合并或调整边界也应进入候选方案。

消息队列不能自动消除耦合。如果调用方发送消息后仍然一直等待结果,或者多个消费者依赖严格的隐含顺序,耦合可能只是转移到了另一条链路上。

五、如何判断治理有效?

选择一个近期确实发生过的变更,在调整后验证它能否只修改必要的服务;演练一个依赖失败,检查影响范围是否符合预期;让团队独立完成发布,确认没有遗漏的人工同步步骤。

如果你已有 .NET 微服务,但发布和故障仍然相互牵制,可以先做一次架构依赖评估。交付重点应是关键耦合点、边界调整建议和可验证的治理顺序,而不只是换一套组件。