ARTICLE / 3 MIN READ

消息队列如何给高并发链路削峰

以订单通知和库存同步为例,说明分区、确认、重试、死信与重复消费应该如何组合。

消息队列的第一价值是把瞬时流量变成消费者能够处理的稳定流量,第二价值是把不需要立即完成的动作从主链路中移走。它不会凭空提高系统总吞吐,反而会引入投递、重复和积压问题。

找出适合异步化的动作

发送短信、更新搜索索引、生成报表、刷新推荐和记录行为通常可以异步。扣库存、确认支付、写订单状态等影响用户结果的动作,除非有明确的最终一致性设计,否则不应简单丢进队列。

同步接口可以返回业务单号和受理状态:

请求 -> 校验 -> 写入订单/任务 -> 发布事件 -> 返回已受理
                                      |
                                      v
                         消费者执行通知、索引和统计

分区和消费者组

Kafka 等日志型队列通常按 Key 选择分区。订单事件使用订单号作为 Key,可以保证同一订单的事件有序,同时让不同订单并行处理。

分区数决定并行上限,消费者数超过分区数时不会继续提升吞吐。分区也不是越多越好,过多会增加文件句柄、选举和重平衡成本。

可靠投递的三件事

  1. 生产者确认:使用可靠确认模式,记录发送失败。
  2. 消费者提交:业务处理成功后再提交 offset。
  3. 重试与死信:可恢复错误延迟重试,不可恢复错误进入死信并告警。

“至少一次”投递意味着重复消息是正常情况。消费者必须用事件 ID、业务唯一键或状态机保证幂等。

处理积压

监控不只看队列长度,还要看最老消息年龄、生产速率、消费速率和重试比例。积压时先判断是突发流量、下游变慢还是消费者异常,再选择扩容、限速、降级或暂停非核心生产者。

消费者扩容前要确认下游数据库和第三方 API 能否承受,否则只是把积压从队列搬到连接池和超时重试。

事件版本与回放

事件体应包含事件 ID、类型、版本、发生时间、聚合 ID 和最小业务字段。消费者只依赖自己需要的字段,并保留向后兼容策略。重要事件写入不可变日志,便于重放和对账。

队列设计的验收标准是:消息丢失可发现、重复可处理、积压有边界、死信有人接、回放不会改乱已经完成的业务状态。

GITHUB DISCUSSION

评论与回复

评论保存在 GitHub Discussions,登录 GitHub 后即可参与,发布和回复都在本页完成。

评论区进入视口后自动加载。