连载中 2/20

服务拆分:按什么刀口切才不会后悔

2026-08-22 · 1488 阅读 · 0 评论 · 0 赞

一张互相绕圈的调用图

拆完半年,架构图变成毛线球:订单服务调商品服务拿价格,商品服务反过来调订单服务查销量,库存服务两边都要问一句。改一个运费规则,评审发现要动四个服务;一次大促压测,得把整条链上的服务全部拉起来。这不是微服务,这是把单体拆开了部署。

问题不在拆,在刀口。按技术分层切(一个订单服务、一个商品服务、一个通知服务),或者按代码顺手切,业务概念的缝隙就会长成服务之间的缝隙。这一篇讲怎么让边界跟着业务走,而不是跟着代码走。

限界上下文:同一个词,几个意思

DDD 里实战价值最高的概念是限界上下文:同一个业务名词,在不同上下文里含义不同,就该是不同的模型。"商品"在目录上下文里是名称、图片、详情页;在库存上下文里只是可售数量与仓库位置;在营销上下文里是价格与促销规则。三个"商品",三套模型,各归各的服务——硬捏成一个商品中心大服务,每次改动都要给三方让路。

找上下文的实操办法:拉着业务方把核心流程的事件列出来——订单已创建、库存已扣减、优惠券已核销——事件归属清楚的地方就是上下文的墙,事件说不清归属的地方,多半是边界还没想清楚。

粒度:宁粗勿细

方向定了,粒度看三条:能力内聚——一个服务对外提供一个说得完整的能力,改一个常见需求的改动尽量落在一个仓库;团队规模——一个服务配一个吃得住它的团队;数据内聚——一个服务的数据尽量落在同一个事务边界里。先拆粗一点,跑半年按痛点再拆细,好过一上来拆出二十个微型服务。

维度拆太细的信号拆太粗的信号
发布粒度改一行要发三个服务任何需求都要回归全量
调用拓扑同步调用绕环、层层深服务之间几乎不调用
数据边界一个事务穿两个库十个业务挤一张大表

数据归属:谁的数据谁说了算

服务边界画完,数据边界跟着画:每个服务独占自己的库,别的服务要用,走接口或事件,禁止直连别人的表。共享表是分布式单体的头号元凶——表结构一动,四个服务同时哑火。跨服务读数据先分两类:强一致的走同步调用并备好降级,最终一致的走事件,让数据以副本形式流过去。

// 反例:跨服务直连库(共享表)
orderMapper.insert(order);          // orders 表
inventoryMapper.deduct(skuId, n);   // 直接写库存服务的表 —— 禁止

// 正例:各自写自己的库,跨域走 API 或事件
orderService.create(order);                       // 订单域写自己的库
eventBus.publish(new OrderCreatedEvent(order));   // 库存域订阅事件自行扣减

验收边界的三个问题

边界草案出来,用三个问题验收:这个服务的能力能用一句话说清吗——说不清就是拆散了;改一个常见需求要动几个服务——超过两个就要警惕;它挂了影响谁——影响面要和业务重要性匹配。三问都过,边界才算立住。下一篇进入基础设施:实例天天变,调用方去哪找到彼此。

☕
503

10 年全栈工程师 · 503咖啡馆主理人

#服务拆分#限界上下文#DDD#数据归属#微服务边界

评论 (0)

热门推荐

连载中 11/22

主从搭建实操:从零配出一主两从

光讲原理不过瘾?手把手搭一主两从:my.cnf 六个参数、复制账号、GTID、CHANGE REPLICATION SOURCE TO、SHOW REPLICA STATUS 验收,附翻车排查清单。

#MySQL#主从复制#GTID#主从搭建#高可用
2026-05-07 · 10101 阅读 · 0 评论 · 0 赞
连载中 16/22

连接池:HikariCP 参数与连接风暴

连接池不是越大越好:8 核机器配 1000 连接反而更慢的数学原理,HikariCP 四个必调参数,maxLifetime 与 wait_timeout 的隐形陷阱。

#MySQL#连接池#HikariCP#maxLifetime#连接风暴
2026-05-10 · 9873 阅读 · 0 评论 · 0 赞
连载中 4/16

缓存穿透:恶意 ID 打穿 MySQL 的四道防线

请求的数据在缓存和数据库里都不存在时,缓存形同虚设。聊聊参数校验、空值缓存、布隆过滤器、限流熔断四道防线的原理与组合打法。

#Redis#缓存穿透#布隆过滤器#高可用
2026-05-16 · 9294 阅读 · 21 评论 · 287 赞