MQ 如何保证消息幂等?(17/31)

上半场靠 inner-msg-id,下半场靠 biz-id——幂等不只是 MQ 的事

即时通讯架构实践第 17 课封面:即时通讯17:MQ 如何保证消息幂等

上半场靠 inner-msg-id,下半场靠 biz-id——幂等不只是 MQ 的事

《即时通讯架构核心技术》第 17 篇:MQ 如何保证消息幂等。

《MQ如何实现,消息必达?》消息必达,架构设计上有两个核心设计点:

1. 消息落地;

2. 消息超时、重传、确认;

但消息重传可能导致receiver收到重复的消息,从而对业务产生影响。

MQ如何实现消息幂等呢?这还是得从MQ的消息发送流程说起。

MQ 消息投递的上下两个半场

如《MQ如何实现,消息必达?》所述,MQ能解除发布订阅者之间的耦合,它将消息投递解耦成上下两个半场:

箭头1,上半场:发送方将消息投递给MQ;

箭头2,下半场:MQ将消息投递给接收方;

MQ要想实现幂等,上下半场都必须做到幂等。

上半场,如何做到幂等?

上半场:发送方投递消息给 MQ

MQ消息投递上半场,流程见上图123:

1. sender将消息发送给MQ-server;

2. MQ-server将消息落地;

3. MQ-server回调sender;

如果步骤3超时,步骤1会重传,会导致步骤2收到重复的消息。此时,

重发方是:MQ-client

接收方是:MQ-server

消息的收发在MQ系统内闭环,可以由MQ来实施消息幂等。

MQ如何实施消息幂等?

为了避免步骤2落地重复的消息,对每条消息,MQ系统内部必须生成一个inner-msg-id,作为去重和幂等的依据。

这个inner-msg-id的特性是:

1. 全局唯一;

2. 由MQ生成,具备业务无关性,对消息发送方和消息接收方都透明;

有了这个inner-msg-id,就能保证上半场重发,也只有1条消息落到MQ-server的DB中,实现上半场幂等。

下半场,如何做到幂等?

下半场:MQ 投递消息给接收方

MQ消息投递下半场,流程见上图456:

4. MQ-server回调receiver;

5. receiver收到消息,处理业务逻辑,将ACK发送给MQ-server;

6. MQ-server收到ACK,将之前已经落地的消息删除,流程结束;

如果步骤5超时,步骤4会重传,会导致业务处理方收到重复的消息。此时,

重发方是:MQ-server

接收方是:业务处理方

消息的收发不能在MQ系统内闭环,只能由业务处理方来保证消息幂等。

业务处理方如何实施消息幂等?

在消息实体中,必须有一个biz-id,作为去重和幂等的依据,这个biz-id的特性是:

1. 对于同一个业务场景,全局唯一;

2. 由业务消息发送方生成,业务相关,对MQ透明;

3. 由业务消息接收方负责判重,以保证幂等;

最常见的biz-id有:

1. 订单id,业务方有义务避免重复生成;

2. 支付id,业务方有义务避免重复扣款;

3. 帖子id,业务方有义务避免重复发布;

…

总结

MQ要想实现幂等,上下半场都必须做到幂等。

上半场:

1. MQ-client生成inner-msg-id,保证上半场幂等;

2. inner-msg-id全局唯一,业务无关,由MQ保证;

下半场:

1. 业务发送方带入biz-id,业务接收方去重保证幂等;

2. 这个biz-id对业务唯一,业务相关,对MQ透明。

幂等性,不仅对MQ有要求,对业务上下游也有要求,那些骂MQ无法保证幂等的架构师,其实自己…

检验一下

检索练习 · 两个半场
MQ 将消息投递解耦成哪两个半场?

检索练习 · 上半场幂等
上半场的消息幂等靠什么实现?

检索练习 · 下半场幂等
为什么下半场的幂等只能由业务处理方保证?

检索练习 · biz-id 的特性
关于 biz-id,下列哪项描述是错的?

本篇一手来源

想深挖一层,读这篇:《MQ系统架构终极指南》(英文)。

文章比较系统,视频比较直观。

消息不重复了,那消息的顺序怎么保证?——第 18 篇,ID 串行化如何保证消息顺序性。

知其然,知其所以然。思路比结论更重要。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

京ICP备2025137728号-3