← 返回 FDE 培养总览 FDE 培养 · 知识点深化 · 微服务实战
知识点深化 · 微服务实战

微服务实战:服务拆分、服务间通信、分布式事务、服务治理

单体应用拆成微服务不是"把代码分成几个文件夹"那么简单。这一页讲透 FDE 在客户现场真正会用到的微服务工程:按业务域怎么拆、服务间同步调用和异步消息怎么选、分布式一致性怎么兜底、注册中心和网关怎么配、分布式追踪怎么搭。

① 小白第一课怎么学(5 步走,约 100 分钟)

先抓住"按业务拆"这个核心,微服务不是目的,是手段。

1理解为什么拆(15 分钟)
读②③:单体的痛 vs 微服务的代价。
2学拆分原则(20 分钟)
读④:按业务域拆,数据库 per 服务。
3通信方式(25 分钟)
同步 HTTP vs 异步 MQ,各自适用场景。
4治理三件套(25 分钟)
注册中心、网关、分布式追踪。
5刷题巩固(15 分钟)
做⑥⑦⑩。
本课小目标学完你要能:① 判断什么时候该拆微服务;② 按业务域拆出合理的服务边界;③ 选对同步调用还是异步消息;④ 用本地消息表解决分布式一致性。

② 一图看懂:微服务架构全景

微服务架构 API 网关 路由/鉴权/限流 Nginx/Kong 业务服务集群 user/order/payment 每个服务独立数据库 注册/配置中心 Nacos/Consul 服务发现/配置 消息队列 MQ Kafka/RabbitMQ 异步解耦/削峰 分布式追踪 Jaeger/OTel 易错:拆太细/循环依赖 跨服务调用满天飞
读法:网关是统一入口,业务服务按业务域拆、各自有库,注册中心管寻址,MQ 做异步解耦,追踪管排障。

③ 本质直觉:微服务就是"按业务分公司"

想象一家大公司。一开始所有人在一个办公室(单体),大家都能用所有资源。人多了之后开始乱:互相干扰、发布慢、沟通成本高。

微服务就是把公司拆成几个独立部门:用户部、订单部、财务部。每个部门有自己的数据库(文件柜),部门之间打电话(API)或者发邮件(MQ)沟通。

部门之间不能互相翻文件柜——这就是"数据库 per 服务"。要拿数据得通过对方的 API,不能直连数据库。这样一个部门崩了不会拖垮全公司。

代价是:部门之间沟通要走流程,跨部门事情慢。但部门内部是高效的。

单体:一个办公室所有人 用户部 自己的文件柜 订单部 自己的文件柜 财务部 自己的文件柜 部门之间:打电话(API)或发邮件(MQ) 不能互相翻文件柜(直连数据库) 好处:一个部门崩了不影响别人
什么时候不该拆团队就 3-5 人、业务还在快速验证期、日活不高——单体加模块化分层比微服务划算。微服务是"规模到了"之后的选择,不是政治正确。

④ 完整体系:拆分原则、通信方式、一致性、治理

服务拆分对照表

维度正确做法错误做法
拆分依据按业务域(DDD 限界上下文)按技术层(controller/service/dao)
数据库一个服务一个 schema多个服务共享一个库
服务粒度先粗后细,逐步拆一次拆成几十个超细服务
依赖方向单向依赖,底层不依赖上层循环依赖

同步 vs 异步通信

方式技术优点缺点适用场景
同步 HTTPREST/gRPC简单直接、立刻拿结果耦合高、下游挂了跟着挂需要实时结果的核心链路
异步 MQKafka/RabbitMQ解耦、削峰、可重试调试难、最终一致通知、日志、非核心路径

分布式一致性方案

方案原理适用场景
本地消息表本地事务里写业务+消息,后台 relay 发 MQ最常用,性价比最高
TCCTry-Confirm-Cancel 三步资金类强一致,成本高
Saga一串本地事务+反向补偿长流程业务

本地消息表代码骨架

# 同一个本地事务里写业务数据 + outbox 消息
BEGIN;
  INSERT INTO orders (id, user_id, total) VALUES (123, 1, 99);
  INSERT INTO outbox (topic, payload) VALUES ('order.events', '{"order_id":123}');
COMMIT;

-- 后台任务:扫 outbox 发 MQ,发完标记
UPDATE outbox SET sent=true WHERE id=?;

服务治理三件套

组件作用常见实现
注册中心服务启动注册自己地址,调用方发现地址Nacos/Consul/etcd
API 网关统一入口:路由、鉴权、限流Nginx/Kong/APISIX
分布式追踪trace_id 透传,看一个请求跨了哪些服务Jaeger/OpenTelemetry

⑤ 用法场景与典型例题

例1(拆分判断)一个电商单体有用户、商品、购物车、订单、支付、库存、通知。你怎么拆?
按业务域拆,先粗后细。
第一刀:用户服务、商品服务、订单服务(核心三域)。
第二刀:支付服务、库存服务(独立逻辑重)。
第三刀:通知服务(纯异步,最容易拆)。
购物车先跟订单放一起,别一次拆太碎。
答案:按业务边界逐步拆,不要按技术层拆。
例2(同步异步选择)下单后要发短信通知用户,用同步还是异步?
看是否在核心路径上。
发短信不影响下单主流程,挂了也不影响用户体验。
应该用异步消息:下单成功发一条 MQ 消息,通知服务消费发短信。
答案:非核心路径用异步,解耦+削峰+不拖慢主流程。
例3(分布式一致性)下单要同时写订单表和扣库存,怎么保证?
跨服务事务,用最终一致方案。
推荐本地消息表:订单服务在本地事务里写订单 + 写 outbox 消息,后台 relay 发 MQ,库存服务消费消息扣减。
扣减失败就走补偿(发退款消息)。
不要强上分布式事务(2PC),性能差还复杂。
答案:本地消息表 + MQ,最终一致即可。

⑥ 高频错误诊断(4 条)

错误 1:按技术层拆服务把 controller 层拆一个服务、service 层拆一个——这是最常见也最蠢的拆法。每次改业务要跨三个服务。正确做法是按业务域拆:订单服务管所有订单相关的代码。
错误 2:多个服务共享一个数据库看似方便,实际耦合死了。改表结构要协调所有服务,跟单体没区别。一个服务独占一个 schema,别的服务只能通过 API 拿数据。
错误 3:同步调用不设超时下游服务卡住,你的线程被占满,整个服务雪崩。所有 HTTP 调用必须设 timeout,再加重试和熔断。
错误 4:拆太细,几十个微服务运维成本爆炸。一个请求跨 10 个服务,排障要疯。先粗后细,有真实痛点了再拆。

⑦ 考点真题演练(4 题)

考点分布

考法出题形式应对
拆分原则判断拆法对不对按业务域、数据库 per 服务
通信选择场景选同步/异步核心同步、非核心异步
一致性跨服务事务怎么处理本地消息表最常用
治理注册中心/网关作用服务发现、统一入口

真题基础1. 微服务应该按什么拆分?

真题中档2. 下单后发通知短信,用什么通信方式?

真题中档3. 跨服务数据一致性,FDE 最常用的方案是?

真题拔高4. 服务 A 调服务 B 超时了,下列哪个处理最不恰当?

⑧ 必背知识点卡

拆分:按业务域拆,不按技术层 一个服务一个库
通信:核心链路同步 HTTP,非核心路径异步 MQ 同步必设超时
一致性:本地消息表最常用,别硬上 2PC 最终一致就够
治理:注册中心管寻址、网关管入口、追踪管排障 三件套
粒度:先粗后细,别一次拆几十个 运维成本爆炸
依赖:单向依赖,不能循环 底层不依赖上层

⑨ 应用输出:设计一个简单的微服务拆分方案

场景:一个内容平台,有用户、文章、评论、点赞、通知
① 识别业务域:用户域(注册/登录/资料)、内容域(文章发布/编辑)、互动域(评论/点赞)、通知域(消息推送)。
② 第一版拆 3 个服务:用户服务、内容服务(文章+评论先放一起)、通知服务。点赞先跟内容放一起,不用单独拆。
③ 数据库:每个服务独占一个 schema,用户服务管 users 表,内容服务管 articles/comments 表。
④ 通信:文章发布后发 MQ 消息,通知服务消费后给关注者推送——异步解耦。文章详情页需要用户昵称,同步 HTTP 调用户服务拿。
⑤ 治理:Nacos 做注册中心,Nginx 做网关,OpenTelemetry 做链路追踪。
口述设计思路"先按业务域粗拆三个服务,各自有独立数据库;核心数据查询走同步 API,通知类走异步 MQ;注册中心管服务发现,网关统一入口,追踪排障。"

⑩ 分层练习 15 题(基础 5 + 中档 5 + 拔高 5)

▍基础 5 题

基础1微服务按什么拆分?
业务域(DDD 限界上下文),不按技术层。
基础2每个微服务有自己的数据库吗?
有。数据库 per 服务,别的服务不能直连它的表。
基础3注册中心是干什么的?
服务启动时注册自己的地址,调用方从中发现可用服务列表。解决"服务 IP 动态变"的问题。
基础4API 网关的作用?
统一入口:路由转发、鉴权、限流、日志。业务服务不用关心这些横切关注点。
基础5同步调用为什么要设超时?
防止下游卡住拖死整个服务(线程池耗尽、雪崩)。必须设 timeout,不能无限等。

▍中档 5 题

中档6什么时候该用异步 MQ 而不是同步 HTTP?
非核心路径、不需要立刻返回结果的场景(如发通知、写日志、发邮件)。解耦+削峰+失败可重试。
中档7本地消息表解决什么问题?
解决"本地事务和发消息的原子性"问题。同一个本地事务里写业务数据+outbox 消息,保证要么都成功要么都失败。
中档8什么是循环依赖?为什么要避免?
A 调 B、B 又调 A。导致发版顺序排不出来、改一处两边都要改。要建单向依赖方向图,底层不依赖上层。
中档9分布式追踪解决什么问题?
一个请求跨多个服务,日志散在多台机器。trace_id 透传+可视化链路,能定位慢在哪个服务哪一步。
中档10微服务一定比单体好吗?
不是。小团队、业务简单时单体更高效。微服务带来的分布式成本,只有规模上去后才划算。

▍拔高 5 题

拔高11TCC 和本地消息表怎么选?
大多数业务用本地消息表(简单可靠);资金类强一致要求高的才上 TCC(成本高、开发复杂)。
拔高12服务 A 调 B 失败了,重试要注意什么?
只对幂等操作重试;指数退避(别立刻重试打爆);设最大重试次数;最终失败要降级兜底。
拔高13为什么多个服务不能共享一个数据库?
耦合死了:改表结构要协调所有服务,跟单体没区别。服务自治的底线就是自己的库自己管。
拔高14怎么避免拆太细?
先粗后细:一开始合并相关功能,有真实痛点(独立扩缩容、发布互相影响)了再拆。不要为了拆而拆。
拔高15一个请求跨 5 个服务超时了,怎么定位?
用分布式追踪(Jaeger/OTel)看 trace 里每个 span 的耗时,找到最慢的那个服务,再去查那个服务的日志和监控。

⑪ 记忆口诀 + 7 天复习计划

三句口诀 ① 按业务拆服务,一个服务一个库。
② 核心同步设超时,非核心异步走 MQ。
③ 一致性靠本地消息表,治理三件套别少。
天任务自检
第 1 天读②③,画一遍微服务全景图能说清每个组件作用
第 2 天背拆分原则 + 做基础 1-5基础全对
第 3 天同步 vs 异步场景题选得对
第 4 天做中档 6-10,理解本地消息表能画 outbox 流程图
第 5 天做拔高 11-15 + 真题 4 题会设计拆分方案
第 6-7 天口述一个微服务架构设计,默写组件清单不看资料全默对

← 返回 FDE 培养总览