← 返回题目列表

微服务边界为什么要结合限界上下文来划分?

高频 困难 第 15 / 25 题 更新于 2026/08/03
微服务限界上下文DDD服务拆分

简化版

微服务边界不能只按表、接口或技术模块划分,更应该结合业务能力和限界上下文。

限界上下文强调:同一个词在不同业务域里可能含义不同,每个上下文拥有自己的模型、规则和数据边界。

如果边界划得好,服务可以独立开发、独立发布、独立扩容,数据所有权清晰。

如果边界划错,就会出现跨服务事务多、接口互相套娃、共享数据库、频繁联调和分布式单体。

详细版

面试中可以从三个层次回答。

第一,业务边界。服务应该围绕稳定的业务能力拆分,例如订单、支付、库存、会员、营销,而不是简单按 Controller、Service、DAO 分层拆。

第二,数据边界。一个服务应该拥有自己的核心数据,其他服务通过 API 或事件获取数据,而不是直接读写它的表。

第三,变更边界。经常一起变化的能力可以先放在一个服务里,经常独立变化的能力才适合拆开。

业务能力
  |
  v
限界上下文 -> 数据所有权 -> 服务边界
                         |
                         v
                  API / Event 协作

可以这样比较:

拆分方式问题更好的做法
按表拆业务流程跨很多服务按业务能力聚合数据
按技术层拆远程调用替代本地方法保持服务内高内聚
按团队随意拆边界随组织摇摆结合业务域和变更频率
共享数据库数据所有权不清晰每个服务负责自己的数据

伪代码表达服务边界时,可以强调只能通过契约访问:

class OrderService:
    def create_order(self, command):
        order = Order.create(command)
        self.order_repository.save(order)
        self.event_bus.publish("OrderCreated", order.to_event())
        return order.id

这里订单服务发布领域事件,库存服务订阅事件处理库存,而不是订单服务直接修改库存表。

完整版教学

一、先看这个问题为什么高频

微服务拆分是架构面试里最容易追问的题。

很多候选人会说按业务拆,但面试官继续问“业务边界怎么判断”时,就需要限界上下文、数据所有权、变更频率这些更具体的标准。

这道题真正考的是你有没有经历过服务拆细之后的协作成本。

二、限界上下文是什么

限界上下文来自领域驱动设计。

它强调模型只在特定上下文内成立。

例如“用户”在账号系统里关注登录名、手机号、密码和安全策略;在营销系统里关注会员等级、标签和优惠资格;在客服系统里关注工单、投诉和服务记录。

这些模型不一定应该放在同一个服务里。

三、为什么不能只按数据库表拆

按表拆看起来清晰,实际很容易造成跨服务事务。

例如下单同时涉及订单表、库存表、优惠券表、支付流水表,如果每张表都拆成一个服务,一次下单就会变成一长串远程调用。

远程调用越多,超时、重试、部分成功和排障成本越高。

微服务拆分的目标不是让服务数量变多,而是让业务边界更清楚、变化更独立。

四、服务边界要看数据所有权

一个服务应该拥有自己的核心数据。

其他服务如果需要这部分数据,应该通过接口查询、事件订阅、数据同步或读模型获取。

直接跨库读写会破坏边界,因为任何表结构变化都会影响多个服务。

如果多个服务都能改同一张表,就很难判断规则应该放在哪里。

五、服务边界要看变更频率

经常一起改的功能拆开,发布会变复杂。

经常独立改的功能放在一起,又会互相拖累。

所以拆分时要看需求历史和团队协作方式。

如果订单状态和支付状态总是一起变更,可以先保持较近的边界;如果营销规则经常独立迭代,就适合单独服务化。

六、拆分后的协作方式

服务之间通常有两类协作。

同步协作适合需要立即返回结果的场景,例如查询价格、校验库存。

异步协作适合不要求立即完成的场景,例如发送通知、更新积分、同步搜索索引。

同步调用要关注超时、重试、熔断和降级。

异步事件要关注幂等、顺序、重复消费和最终一致。

七、拆错边界的信号

如果出现这些信号,说明边界可能有问题:

  1. 一个需求每次都要改很多服务。
  2. 服务之间频繁同步调用。
  3. 多个服务共享同一个数据库。
  4. 大量字段只是透传,没有业务判断。
  5. 测试必须启动一整套系统。
  6. 发布必须多个服务同时上线。

这些都是分布式单体的典型表现。

八、常见误区与追问

  • 误区:服务越小越好。 服务过小会增加网络、事务、测试和发布成本。
  • 误区:限界上下文等于数据库表。 它描述的是业务模型边界,不是物理表边界。
  • 误区:所有数据都实时查询源服务。 高频读场景可以通过事件同步构建读模型。
  • 误区:共享数据库更方便。 短期方便,长期会让服务边界失效。
  • 追问:拆分后跨服务查询怎么办? 可以用冗余字段、CQRS、搜索索引、数据同步或聚合服务。
  • 追问:拆分后事务怎么办? 优先调整边界,其次考虑 Saga、可靠消息和补偿。

九、加强记忆

  1. 服务边界先看业务能力。
  2. 限界上下文定义模型含义。
  3. 数据所有权要清晰。
  4. 经常一起变的不要强拆。
  5. 跨服务事务多说明边界可能错了。
  6. 共享数据库会破坏自治。
  7. 拆分目标是高内聚、低耦合、可独立演进。