赞
踩
在应用程序中,幂等性简单来讲就是,一个方法无论被调用多少次,都不会改变第一次调用后的结果.
a)幂等
案例:
redis 中的 setnx 操作,表示如果 key 不存在,则设置,如果 key 存在则不设置.
假设 key 不存在,那么通过 setnx 操作后,就会成功设置 key,并且在这之后无论多少次调用 setnx,都不会在影响第一次调用 setnx 操作后的结果.
b)非幂等
案例:
i++ 这个操作就是非幂等的.
假设 i 初始为 0, 第一次调用后会 i = 1,并且后面每次调用都会影响第一调用后的结果(第二次 i++ ,i 就等于 2).
a)基本概念
对于 MQ 而言,幂等性就是指统一消息,无论被消费多少次,都不会改变第一次消费后的结果.
一般消息中间件的消息传输保证分为 三个层级:
最多
被一次消费一次. 消息可能会丢失
,但肯定会重复传输
.最少
被一次消费一次. 消息肯定不会丢失
,但可能会重复传输
.恰好
被消费一次. 每条消息肯定肯定不会丢失
,并且只传输一次
.Ps:RabbitMQ 支持
At most once
和At least once
.(不可能有任何一个 MQ 支持Exactly once
).
因此,对于可靠性要求高的场景,建议使用 At most once
,
b)哪些场景会导致消息发送重复呢?
MQ 消费者幂等性的解决方案主要有以下两种:
Note:
全局唯一ID
这个方案基本上就覆盖了 90% 的应用场景. 可能网上也还有很多其他资料描述其他的方法,但基本上都是围绕 全局唯一ID 的拓展(本质的思想都一样).
a)全局唯一ID:
Ps:以上过程,使用 Redis 的 setnx 操作就可以保证幂等性 ->
- setnx 返回 1,说明 key 不存在,设置成功,进而说明之前没有消费,正常消费即可.
- setnx 返回 0,说明 key 存在,设置失败,进而说明之前消费过,抛弃这条消息.
b)业务逻辑判断:
例如订单系统,通过检查数据库中 status 字段(枚举),是否是已经付款的状态,如果已经付款,就抛弃该消息.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。