RabbitMQ应用问题 - 幂等性保障

文章目录

幂等性保障


理论

在应用程序中,幂等性简单来讲就是,一个方法无论被调用多少次,都不会改变第一次调用后的结果.

a)幂等案例:

redis 中的 setnx 操作,表示如果 key 不存在,则设置,如果 key 存在则不设置.

假设 key 不存在,那么通过 setnx 操作后,就会成功设置 key,并且在这之后无论多少次调用 setnx,都不会在影响第一次调用 setnx 操作后的结果.

b)非幂等案例:

i++ 这个操作就是非幂等的.

假设 i 初始为 0, 第一次调用后会 i = 1,并且后面每次调用都会影响第一调用后的结果(第二次 i++ ,i 就等于 2).

MQ 的幂等性

a)基本概念

对于 MQ 而言,幂等性就是指统一消息,无论被消费多少次,都不会改变第一次消费后的结果.

一般消息中间件的消息传输保证分为 三个层级:

  • At most once:同一个消息最多被一次消费一次. 消息可能会丢失,但肯定会重复传输.
  • At least once:同一个消息最少被一次消费一次. 消息肯定不会丢失,但可能会重复传输.
  • Exactly once:同一个消息恰好被消费一次. 每条消息肯定肯定不会丢失,并且只传输一次.

Ps:RabbitMQ 支持 At most onceAt least once.(不可能有任何一个 MQ 支持 Exactly once).

因此,对于可靠性要求高的场景,建议使用 At most once

b)哪些场景会导致消息发送重复呢?

  • 生产者发送消息时重复:当开启了生产者确认机制后(例如 confirm),那么当 交换机 成功接收到消息,就会返回 ack,但是由于网络问题,导致生产者没有接收到 ack,那么生产者就会重发消息.
  • 队列给消费者投递时重复:当开启了消费者确认机制后,那么当 消费者 成功接收到消息并正确处理后,就会返回 ack,但是由于网络问题,导致 ack 没有返回给 mq,mq 就会就会重发消息.

幂等性的保障方案

MQ 消费者幂等性的解决方案主要有以下两种:

Note:全局唯一ID 这个方案基本上就覆盖了 90% 的应用场景. 可能网上也还有很多其他资料描述其他的方法,但基本上都是围绕 全局唯一ID 的拓展(本质的思想都一样).

a)全局唯一ID:

  • 给每个消息分配一个唯一ID,比如 UUID、MQ消息唯一ID...
  • 消费者接收到消息后,会先根据 id 判断这个消息是否被消费过(判断 id 是否存在),如果消费过,就放弃处理.
  • 如果没有消费过,消费者就处理消息,处理完成后,就把 id 保存起来(例如 Redis).

Ps:以上过程,使用 Redis 的 setnx 操作就可以保证幂等性 ->

  • setnx 返回 1,说明 key 不存在,设置成功,进而说明之前没有消费,正常消费即可.
  • setnx 返回 0,说明 key 存在,设置失败,进而说明之前消费过,抛弃这条消息.

b)业务逻辑判断:

例如订单系统,通过检查数据库中 status 字段(枚举),是否是已经付款的状态,如果已经付款,就抛弃该消息.

相关推荐
独隅1 小时前
PyTorch 分布式训练完整指南:策略、实现与模型选型
人工智能·pytorch·分布式
架构师老Y2 小时前
011、消息队列应用:RabbitMQ、Kafka与Celery
python·架构·kafka·rabbitmq·ruby
墨北小七4 小时前
小说大模型的分布式训练——张量并行架构设计与实现
分布式
豆豆4 小时前
政务服务平台站群一体化解决方案
大数据·分布式·微服务·cms·政务·网站管理系统·站群cms
昵称暂无15 小时前
分布式事务难题:Seata框架在微服务中的落地实践
分布式·微服务·架构
都说名字长不会被发现6 小时前
分布式场景下的数据竞争问题与解决方案
分布式·乐观锁·悲观锁·redission·redis 分布式锁·数据版本
甘露s6 小时前
分布式与可重入性的一些问题
分布式
juniperhan6 小时前
Flink 系列第 3 篇:核心概念精讲|分布式缓存 + 重启策略 + 并行度 底层原理 + 代码实战 + 生产规范
大数据·分布式·缓存·flink
想你依然心痛6 小时前
HarmonyOS 5.0 IoT开发实战:构建分布式智能设备控制中枢与边缘计算网关
分布式·物联网·harmonyos
lifallen6 小时前
如何保证 Kafka 的消息顺序性?
java·大数据·分布式·kafka