关于MQ的几件小事(三)如何保证消息不重复消费

1.幂等性

幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。 在编程中一个幂等操做的特色是其任意屡次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可使用相同参数重复执行,并能得到相同结果的函数。这些函数不会影响系统状态,也不用担忧重复执行会对系统形成改变。例如,“setTrue()”函数就是一个幂等函数,不管屡次执行,其结果都是同样的.更复杂的操做幂等保证是利用惟一交易号(流水号)实现.redis

简单来讲,幂等性就是一个数据或者一个请求,给你重复来了屡次,你得确保对应的数据是不会改变的,不能出错。数据库

2.出现重复消费场景

(1)首先,好比rabbitmq、rocketmq、kafka,都有可能会出现消息重复消费的问题。由于这个问题一般不是由mq来保证的,而是消费方本身来保证的。
(2)举例kafka来讲明重复消费问题 kafka有一个叫作offset的概念,就是每一个消息写进去,都有一个offset表明他的序号,而后consumer消费了数据以后,每隔一段时间,会把本身消费过的消息的offset提交一下,表明我已经消费过了,下次就算重启,kafka就会让消费者从上次消费到的offset来继续消费。编程

可是万事总有例外,若是consumer消费了数据,还没来得及发送本身已经消费的消息的offset就挂了,那么重启以后就会收到重复的数据。 ide

kafka重复消费示意图.png

3.保证幂等性(重复消费)

要保证消息的幂等性,这个要结合业务的类型来进行处理。下面提供几个思路供参考:函数

(1)、可在内存中维护一个set,只要从消息队列里面获取到一个消息,先查询这个消息在不在set里面,若是在表示已消费过,直接丢弃;若是不在,则在消费后将其加入set当中。post

(2)、如何要写数据库,能够拿惟一键先去数据库查询一下,若是不存在在写,若是存在直接更新或者丢弃消息。cdn

(3)、若是是写redis那没有问题,每次都是set,自然的幂等性。blog

(4)、让生产者发送消息时,每条消息加一个全局的惟一id,而后消费时,将该id保存到redis里面。消费时先去redis里面查一下有么有,没有再消费。rabbitmq

(5)、数据库操做能够设置惟一键,防止重复数据的插入,这样插入只会报错而不会插入重复数据。队列

上一篇《如何保证消息队列的高可用
下一篇《如何防止数据队列数据丢失

相关文章
相关标签/搜索