架构风格与模式58 条

发布-订阅模式

发布者把消息发送到主题,多个订阅者各自消费;解耦生产者与消费者,支持一对多广播与异步削峰,代价是消息顺序、重复消费与积压治理。

发布订阅是什么

发布订阅模式中,发布者把消息发送到主题或交换器,多个订阅者各自消费,发布者不关心谁在消费、消费得快还是慢。它解耦生产者与消费者,支持一对多广播与异步削峰,代价是消息顺序、重复消费、积压与投递语义都需要显式治理。它既可以用在进程内的模块解耦,也可以跨系统承担集成总线角色。

基本信息

核心角色发布者、主题或队列、订阅者、消息代理
交付语义至少一次、至多一次、精确一次,实现成本递增
治理要点消费端幂等、积压监控、死信队列、消息保留策略
常见载体Kafka、RabbitMQ、Pulsar、RocketMQ、云消息服务
推送与拉取推送实时性好,拉取便于消费者控制节奏与背压

投递语义对照

语义机制代价
至多一次发出即忘,不做确认网络抖动或消费失败会丢消息
至少一次重试直到收到确认可能重复,需要消费端幂等
精确一次事务或去重配合,限定在组件范围内实现复杂,跨系统端到端难保证
有序投递按业务键分区,单分区串行跨键并行,顺序只在键内成立

典型使用场景

  • 业务解耦:订单创建后广播事件,库存、积分、通知各自订阅
  • 流量削峰:突发请求写入队列,后端按处理能力匀速消费
  • 一对多通知:一次配置变更需要通知多个节点或子系统
  • 异步任务:耗时操作转为后台消费,缩短接口响应时间
  • 跨系统集成:以主题作为契约,双方不需要直接调用
  • 审计与归档:订阅全量消息写入日志或数据仓库
“至少一次投递加消费端幂等”是工程上使用最广的组合;精确一次通常限定在特定组件与范围内成立,跨系统端到端仍要做去重。
消费者数量超过分区数时,多出的消费者会空闲,扩容前先确认分区数量与消费并行度是否匹配。

易错点

  • 消费端不幂等,重投递导致重复发货、重复发券等业务事故
  • 不设死信队列,处理失败的消息被无限重投,阻塞后续消息消费
  • 分区数不足,消费者扩容后大量实例空闲,吞吐无法提升
  • 把需要强一致的流程改成异步消息后仍假设即时可见,读到的数据不一致
  • 无消费延迟监控,积压数小时后由业务方发现,补偿代价更高

数据来源与参考

  • 《Enterprise Integration Patterns》(Hohpe & Woolf)
  • Apache Kafka 官方文档
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌