DDD跨限界上下文聚合存在性校验:异步方案与HTTP通信疑问
问题背景
我在开发航空公司应用,划分了预订和用户两个限界上下文(Bounded Context):
- 预订限界上下文的聚合结构:
export class Plane { id: UUID reservations: Array<Reservation> seats: Array<Seats> // 其他无关代码 } export class Reservation { id: UUID personId: UUID seatId: UUID }
Plane是聚合根,Reservation是子实体。
- 用户限界上下文的User实体:
export class User { id: UUID // 其他无关代码 }
创建预订的初始逻辑未校验用户存在性,后来改为同步HTTP调用用户服务校验,但存在两个问题:
- 微服务间同步通信增加耦合度;
- 校验后用户被删除,虽可通过
DeletedUser事件后续移除预订,但处理方式不够直观,略显“取巧”。
核心疑问
- 如何将同步通信转为异步通信,同时避免数据竞争导致应用处于无效状态?比如担忧以下场景:
- 用户通过Plane聚合发起预订,未校验用户是否存在;
- 触发校验用户是否存在的事件;
- 用户服务返回“用户存在”事件;
- 用户被删除,用户服务触发“用户已删除”事件;
- 处理用户删除事件,移除Plane中的预订;
- 处理用户存在事件,为已删除用户创建预订。
- 微服务间通过HTTP通信是否属于不良实践?
解答
1. 异步通信下避免数据竞争的方案
要解决事件顺序错乱导致的无效状态问题,核心是通过状态管控、版本追踪或顺序保障来处理,以下是几个落地性强的方案:
方案一:先创建待确认预订,基于版本做冲突校验
- 用户发起预订请求时,预订服务先创建一条待确认状态的预订记录,生成唯一
requestId,并向用户服务发送CheckUserExists事件(携带requestId和userId)。 - 用户服务返回
UserExists事件时,附加用户当前的版本号userVersion;返回UserNotFound则直接标记预订无效。 - 预订服务处理
UserExists事件时,先核对待确认预订是否存在,再检查用户的最新状态:- 如果用户未被删除,且当前版本≥事件中的
userVersion,则将待确认预订转为有效状态; - 如果已存在
UserDeleted事件(且删除操作的版本大于UserExists中的版本),则直接取消该待确认预订。
- 如果用户未被删除,且当前版本≥事件中的
- 收到
UserDeleted事件时,标记该用户所有待确认预订为无效,同时触发已生效预订的取消流程(释放座位、通知用户)。
方案二:用状态字段+定期巡检保障最终一致
- 在预订表中新增
user_valid字段,默认值为pending; - 发起预订时直接创建记录,同时发送
CheckUserExists事件; - 收到
UserExists则将user_valid设为valid,收到UserDeleted则设为invalid并触发取消流程; - 预订服务定期巡检
user_valid=pending的记录,主动调用用户服务校验状态,避免因消息丢失导致的长期待确认。
方案三:基于消息顺序的因果处理
使用支持消息顺序的中间件(比如Kafka按userId分区+时间戳排序),给每个事件添加correlationId(关联同一业务流程):
- 同一
userId的事件会被分配到同一个消息分区,确保按生成顺序处理; - 预订服务处理事件时,先判断当前业务流程的最新状态,比如如果已经处理过
UserDeleted,再收到UserExists就直接忽略。
2. 微服务间HTTP通信是否是不良实践?
不是绝对的不良实践,要结合业务场景判断:
适合用HTTP的场景:
- 必须同步获取结果才能继续的业务(比如你最初的用户存在校验,如果业务要求必须确保用户存在才能创建预订,同步HTTP是最直接的方式);
- 低并发、对延迟不敏感的内部查询操作(比如获取用户基本信息);
- 简单的跨服务调用,不需要复杂的事件驱动逻辑。
不适合用HTTP的场景:
- 高并发的通知类操作(比如订单创建后通知库存),同步HTTP会导致服务阻塞、吞吐量下降;
- 依赖最终一致性的业务流程,同步调用会增加耦合,一旦依赖服务故障,当前服务也会受影响;
- 事件驱动的复杂业务场景,异步消息队列更适合解耦和保障消息可靠性。
总结:HTTP通信本身没问题,关键是不要用同步HTTP实现跨服务的强依赖业务流程。如果可以用异步事件解耦,优先选择异步;但如果业务要求强一致性,同步HTTP调用是合理选择,此时可通过超时、重试、熔断等机制降低耦合风险。
内容的提问来源于stack exchange,提问作者JackG
相关产品推荐
相关产品推荐

