消息颗粒度设计方法

#设计 #最佳实践 #消息队列

总结
  • 消费方多且需求各异:瘦消息 + 查询(只传事件 ID,消费方自己查数据)
  • 消费方固定、需要快照:消息携带数据(按消费方需求裁剪字段)
  • 不推荐"三粒度分级",边界模糊维护成本高
  • 团队消息格式乱可以引入 CloudEvents 规范统一

1. 先说结论

消息设计有两个方向,按场景选:

方案 适用场景 核心思路
瘦消息 + 查询 事件驱动架构,消费方需求各异 消息只传事件标识,消费方自己查数据
消息携带数据 消费方场景固定,不想二次查询 按消费方需求裁剪字段

不推荐"三粒度分级":按字段数量切消息类(粗/中/细)边界模糊,维护三套 DTO 成本高,消费方还是要猜该用哪个。


2. 瘦消息 + 查询(推荐)

消息只携带事件类型和业务 ID,消费方收到后按需调用接口拿完整数据。这是 DDD 事件驱动的标准做法。

{
  "orderId": "123456",
  "event": "ORDER_PAID",
  "occurredAt": "2026-03-14T10:00:00Z"
}
// 消费方:收到消息后自己查需要的数据
@KafkaListener(topics = "order-events")
public void onOrderPaid(OrderEvent event) {
    // 按需查询,要什么取什么
    Order order = orderClient.getOrder(event.getOrderId());
    // 处理业务逻辑...
}

优点

缺点


3. 消息携带数据

消费方场景固定时,直接把需要的字段塞进消息,省去二次查询。

// 按消费方实际需要的字段设计,不多不少
public class OrderPaidMessage {
    private String orderId;
    private Long userId;
    private BigDecimal amount;
    private String paymentMethod;
    private Date paidAt;
    // 只放消费方真正用到的字段
}

什么时候用

注意版本兼容


4. 用 CloudEvents 规范统一消息格式

如果团队消息格式比较乱,可以参考 CloudEvents 规范,统一元数据结构:

{
  "specversion": "1.0",
  "type": "com.example.order.paid",
  "source": "/order-service",
  "id": "A234-1234-1234",
  "time": "2026-03-14T10:00:00Z",
  "datacontenttype": "application/json",
  "data": {
    "orderId": "123456",
    "amount": 99.00
  }
}

Kafka、AWS EventBridge、阿里云 EventBus 都支持这个格式,方便跨系统集成。


5. 怎么选?


相关链接