Yihui’s Blog

什么情况下需要分发消息?

日期:2026-09-27
标签:#面试 #场景设计 #消息队列 #Kafka
难度:简单
来源:牛面场景题
答案说明:独立整理(站内题目标记为 VIP,未读取会员答案)

一句话答案

一个业务事件要触发多个职责独立、演进节奏不同的下游处理时,适合通过发布订阅分发消息。

面试口语版(约 60 秒)

比如订单支付成功后,通知、积分、风控和数据分析都需要知道这件事。让订单服务逐个同步调用,链路会被最慢的下游拖住,新增下游也得改订单服务。这时可以发布一条带事件 ID、订单 ID、发生时间和版本的“支付成功”事件,让各下游按各自的消费者组订阅。Kafka 中不同消费者组可以各自消费同一主题;一个组内部则由成员分担分区,不是每个实例都收到一份。分发后要分别监控各组延迟、处理失败和重试,消费者对重复事件做幂等。若主流程必须等某项结果才能向用户承诺成功,那项操作仍应在主流程中完成或有明确的状态机。

原理与适用场景

flowchart LR
  O[订单服务] -->|支付成功事件| K[Kafka 主题]
  K --> N[通知消费者组]
  K --> P[积分消费者组]
  K --> R[风控消费者组]
  P -->|分区 0| P1[组内实例 A]
  P -->|分区 1| P2[组内实例 B]

图中以两个分区为例;组内实例分摊分区,不会各收到同一分区的完整副本。

  • 跨组分发:每个消费者组维护自己的消费位置,可独立扩缩容、失败重试和回放。
  • 组内分摊:同一分区在一个消费者组内同一时刻由一个成员处理;多个实例不是广播收件人。
  • 事件契约:事件表述已经发生的事实,定义业务主键、事件 ID、版本与字段兼容规则。订阅者不要依赖生产者的内部表结构。
  • 适合:同一事实供多个系统异步处理,且各结果允许在可约定的时间内达到一致。

具体案例与失败分支

积分服务故障时,通知和风控组仍可前进,积分组积压并在修复后按位点重放。重放可能重复执行发积分,因此积分流水以“支付事件 ID + 积分规则”设唯一约束。若通知需在请求返回前确认已发送,单纯分发无法满足这一同步承诺,应改为等待通知结果或把接口语义改成“已受理”。

取舍与易错点

  • 分发减少生产者对下游数量的依赖,却增加事件契约、可观测性、追踪和最终一致性的成本。
  • “同一主题有三个消费者实例”不等于“三份广播”;是否各得一份取决于消费者组。
  • 先界定每类订阅方的失败策略。坏消息重试不能无限阻塞整个分区;隔离处理时仍要保留审计和补偿路径。
  • 保持同一订单相关事件的键稳定,才有机会按分区维持顺序;Kafka 不承诺跨分区全局顺序。

面试官递进追问

  1. 一个主题与多个消费者组的关系是什么? 每组有独立位点,组内成员分摊分区。
  2. 新增订阅方需要改生产者吗? 契约兼容时通常不必;新组从哪里开始消费要按历史回放需求配置。
  3. 某个订阅方处理失败会怎样? 它的延迟与重试独立,但若共享关键下游或 Broker 资源仍可能互相影响,应做容量与隔离设计。

自测

  • 用 60 秒说清“跨组分发”和“组内竞争”的区别。
  • 画出订单支付事件分发给三个系统的图,并指出各系统重复消费的处理位置。
  • 判断“支付成功但积分晚 2 分钟到账”是否可接受,写出需要与业务确认的承诺。

参考资料

核对日期:2026-09-27。

Maintained by · YihuiEdit on GitHub

Keep reading

View all posts

如何为Redis分布式锁设置合理的超时时间?

日期:2026-09-27 标签:#面试 #场景设计 #Redis 难度:中等 来源:牛面场景题 答案说明:独立整理(站内题目标记为 VIP,未读取会员答案) 一句话答案 租约应覆盖可预期的执行、暂停与网络抖动,同时限制故障后的等待;没有可靠耗时上界时用有身份校验的受控续期,并在业务资源侧防止旧执行者写入。 面试…

Read article

怎么用Redis实现可重入的分布式锁?

日期:2026-09-27 标签:#面试 #场景设计 #Redis 难度:中等 来源:牛面场景题 答案说明:独立整理(站内题目标记为 VIP,未读取会员答案) 一句话答案 为同一把锁保存“本次最外层获锁的唯一令牌 + 重入次数 + 租约”;嵌套调用共享该令牌并原子递增,释放时递减,次数归零才删除。新一轮独立获锁必…

Read article

基于 Redis 实现分布式锁有什么优缺点?

日期:2026-09-27 标签:#面试 #场景设计 #Redis 难度:简单 来源:牛面场景题 答案说明:独立整理(站内题目标记为 VIP,未读取会员答案) 一句话答案 Redis 锁接入简单、响应快,适合容忍少量故障窗口内重复执行的任务;租约过期与主从切换可能破坏互斥,关键写入还须在资源侧拒绝旧持有者。 面试…

Read article