返回博客
J
3D人偶 架构 · 演进

从单体到微服务:一次完整的架构演进实战

JJokerChou 2026.06.28 约 6 分钟

很多团队拆微服务是"为了拆而拆",结果服务没解耦,反而多了分布式事务、链路追踪、运维复杂度三座大山。 本文记录一次真实的架构演进:从单体积压到按业务域拆分,重点讲清楚 什么时候该拆、怎么拆、拆完怎么稳——而不是一堆正确的废话。

1先判断:你真的需要微服务吗?

微服务不是银弹。在动手前,先用下面这条清单自检:

⚠️ 如果只是为了"显得先进"而拆,你会收获一个"分布式单体":服务是分开的,但所有调用强耦合、一个接口要串 8 个服务,比单体还难维护。

2服务如何划分:按业务域,而非按技术层

最常见的错误是按技术分层拆(UserController 服务、OrderController 服务),这只会制造大量跨服务调用。正确姿势是领域驱动设计(DDD)的限界上下文。

划分方式例子问题
按技术层(❌)user-api / user-service / user-dao一次请求跨 3 个服务,强耦合
按业务域(✅)user / order / payment / inventory高内聚,域间只通过接口通信

划分原则:

3网关:统一入口与横切关注点

拆完之后,客户端不该直接面对 N 个服务。引入API 网关作为唯一入口,集中处理鉴权、限流、日志、路由:

# 网关路由示例(伪配置)
routes:
  - id: user-service
    uri: lb://user-service
    predicates:
      - Path=/api/user/**
    filters:
      - StripPrefix=1
      - name: RequestRateLimiter   # 限流
  - id: order-service
    uri: lb://order-service
    predicates:
      - Path=/api/order/**
💡 网关只做"薄"的横切逻辑。业务判断(如"该用户能否下单")必须留在对应服务内,否则网关会慢慢变成第二个单体。

4熔断、降级、限流:分布式系统的三道防线

服务一多,局部故障会被放大成雪崩。必须给每个下游调用上保护:

// 用 Sentinel 给下游调用加熔断(伪代码)
try (Entry entry = SphU.entry("orderService.query")) {
    return orderClient.query(id);
} catch (BlockException e) {
    return fallbackOrder(); // 降级:返回缓存/默认值
}

5数据拆分:最难的一公里

最难的是共享数据库。单体时期一张表大家共用,拆分时要把数据"连根拔起":

⚠️ 跨服务事务是深坑。能避则避:优先用最终一致性 + 消息队列,而非强一致分布式事务(详见本博客《分布式事务终极指南》)。

6可观测性:看不见就管不了

单体靠看日志就能排错,微服务必须上"三件套":

// 一次请求应带统一 traceId,贯穿所有服务
traceId: "a1b2c3d4-..."  // 网关生成 → 透传给每个下游

7演进小结

架构演进没有"标准答案",只有"当时当下最合适的取舍"。先让单体跑顺,再在真实痛点出现时有的放矢地拆—— 这才是稳健的演进,而不是一场昂贵的重构豪赌。

© 2026 JokerChou's Blog · 用 ❤️ 与 ☕ 制作 · 返回博客首页