Microservices Architecture Guide
Service decomposition, communication styles, API gateway, service discovery, resilience patterns and observability.
Splitting a Monolith
A microservice is a service with its own codebase, deployment and data store, outliving any team. Decompose around business capability, not technical layer: 'orders', 'users', 'payments' — not 'ctrl', 'dao'. The litmus test for a split is whether a service can be developed, deployed and scaled without coordinating with others.
| 维度 | 单体 | 微服务 |
|---|---|---|
| 部署 | 一次发全站 | 按服务独立发布 |
| 技术栈 | 统一 | 按服务自由选型 |
| 故障域 | 一处崩溃全站 | 故障可隔离(配熔断) |
| 数据 | 共享数据库 | 每服务独占库 |
| 复杂度 | 调用简单 | 网络/一致性成本高 |
| 适用规模 | 小团队、MVP | 多团队、大流量 |
Communication Styles
同步(请求-响应)
REST/HTTP 通用、可调试、跨语言(默认选择)
gRPC Protobuf 编码、HTTP/2 长连,内部调用低延迟
GraphQL 前端聚合多源数据,BFF 场景
异步(事件驱动)
消息队列 削峰、解耦:Kafka / RocketMQ / RabbitMQ
事件 发布后立即继续,最终一致
选型经验:
需要结果 → 同步;通知/审计/广播 → 异步
链路超过 2 跳同步调用 = 风险信号,考虑异步化
长耗时任务 → 提交任务 + 通知(回调/轮询)
Gateway, Discovery and Config
API 网关(Nginx / Kong / APISIX / Spring Cloud Gateway):
统一鉴权、限流、灰度路由、TLS 终止、日志监控
前端只依赖网关,内部结构变化不泄漏
服务发现:
客户端发现:从注册中心(Nacos/Consul/Eureka)拉实例直连
服务端发现:请求经过代理(Envoy/Kong)按注册表转发
K8s 环境:Service + DNS 即注册中心
配置中心(Nacos / Apollo / Consul KV):
环境隔离(dev/test/prod)+ 灰度发布
下发后客户端缓存 + 监听变更热更新
容错三件套(Sentinel / Hystrix / Resilience4j):
超时 → 熔断 → 降级(返回兜底结果或缓存)
舱壁隔离:不同下游独立线程池/信号量
Every cross-service call needs a timeout and a fallback. Without timeouts, one slow dependency cascades into a full outage.
Distributed Transaction and Observability
跨库一致性兜底(不要追求强一致):
1) 本地消息表:业务库落消息 + 定时扫出投递(最常用)
2) 事务消息:RocketMQ 半消息 + 回查
3) Seata AT/TCC:侵入或一致性要求高的资金场景
4) Saga:长流程,每步配补偿
通用要求:消费者幂等、可回放、有对账
链路追踪三剑客:
Trace = 全链路一条(traceId 透传,MDC/Baggage)
Metrics = Prometheus(QPS、延迟分位、错误率)
Logs = ELK/Loki,日志必须带 traceId
可观测性目标:出问题先看到(告警),进链路能定位(trace)
日志采集 → 指标聚合 → 链路串联,三者用同一 traceId 串起来从单体到微服务
微服务是拥有独立代码库、独立部署、独立数据存储的服务,其生命周期与团队解耦。按业务能力拆分而非技术分层:「订单」「用户」「支付」,而不是「controller」「dao」。检验拆分是否合理的标准是:这个服务能否不与其他团队协调,就独立开发、部署、扩容。
| 维度 | 单体 | 微服务 |
|---|---|---|
| 部署 | 一次发全站 | 按服务独立发布 |
| 技术栈 | 统一 | 按服务自由选型 |
| 故障域 | 一处崩溃全站 | 故障可隔离(配熔断) |
| 数据 | 共享数据库 | 每服务独占库 |
| 复杂度 | 调用简单 | 网络/一致性成本高 |
| 适用规模 | 小团队、MVP | 多团队、大流量 |
服务间通信
同步(请求-响应)
REST/HTTP 通用、可调试、跨语言(默认选择)
gRPC Protobuf 编码、HTTP/2 长连,内部调用低延迟
GraphQL 前端聚合多源数据,BFF 场景
异步(事件驱动)
消息队列 削峰、解耦:Kafka / RocketMQ / RabbitMQ
事件 发布后立即继续,最终一致
选型经验:
需要结果 → 同步;通知/审计/广播 → 异步
链路超过 2 跳同步调用 = 风险信号,考虑异步化
长耗时任务 → 提交任务 + 通知(回调/轮询)
网关、服务发现与配置
API 网关(Nginx / Kong / APISIX / Spring Cloud Gateway):
统一鉴权、限流、灰度路由、TLS 终止、日志监控
前端只依赖网关,内部结构变化不泄漏
服务发现:
客户端发现:从注册中心(Nacos/Consul/Eureka)拉实例直连
服务端发现:请求经过代理(Envoy/Kong)按注册表转发
K8s 环境:Service + DNS 即注册中心
配置中心(Nacos / Apollo / Consul KV):
环境隔离(dev/test/prod)+ 灰度发布
下发后客户端缓存 + 监听变更热更新
容错三件套(Sentinel / Hystrix / Resilience4j):
超时 → 熔断 → 降级(返回兜底结果或缓存)
舱壁隔离:不同下游独立线程池/信号量
每一条跨服务调用都要配超时和兜底。没有超时,一个慢依赖会级联成全局故障。
分布式事务与可观测性
跨库一致性兜底(不要追求强一致):
1) 本地消息表:业务库落消息 + 定时扫出投递(最常用)
2) 事务消息:RocketMQ 半消息 + 回查
3) Seata AT/TCC:侵入或一致性要求高的资金场景
4) Saga:长流程,每步配补偿
通用要求:消费者幂等、可回放、有对账
链路追踪三剑客:
Trace = 全链路一条(traceId 透传,MDC/Baggage)
Metrics = Prometheus(QPS、延迟分位、错误率)
Logs = ELK/Loki,日志必须带 traceId
可观测性目标:出问题先看到(告警),进链路能定位(trace)
日志采集 → 指标聚合 → 链路串联,三者用同一 traceId 串起来