RocketMQ 集群核心概念-幂等消息-幂等问题的出现
幂等消息-幂等问题的出现
消费者在拿到消息以后,它已经将消息存在DB里面了,它已经完成它的业务了,正常要返回ack,只剩下最后一步提交offset,但是在提交offset的时候,不巧消费者挂掉了,那么意味着这个offset没有办法被提交。
一旦消费者挂掉,这个时候就会触发同组的消费者reblacne机制,触发重新分配。也就就是把之前消息的messagequenue从新分配给新的consumer,也就是同组的另外一个消费者。
因为这个消息没有提交offset,所以出现的问题就在于在提交offset的时候,consumer已经挂掉了,那么这个消费者再过来对messagequenue进行消费依然是可以拿到这条消息的。
这在于提交的时候consumer挂掉了,新的消费者拿到这条消息又把这个消息添加到数据库里面。消息的重试可能导致对消息的重复消费。那么就会出现幂等性的问题。
上面两种逻辑都会出现幂等性问题。
可以在业务侧方面去做幂等性的保证
在业务层面有一个单独的组件管理着共享的数据,既然是单独的组件,那么必然数据可以被多个消费者访问。
现在有两个消费者C1 C2。,它就上了mylock1这样一个锁。注意这里做了一个上锁的动作。
如果上锁成功,很显然c2继续上锁,那么c2肯定是失败的。只要分布式锁保证数据不会出现脏读。
c1 c2都想消费一条消息,订单id都是相同的都是1。发现订单id为1那么就要做一件事情,去共享的中间者看看,去尝试上锁。能不能上成功?
如果这地方根本就没有mylock1那么就成功了,那么这个锁就上上去了。那么c1就可以对这条消息进行处理,将消息存放到数据库当中。
c2是在后面来的,也要去管理着共享数据的组件里面有没有mylock 订单id为1的。如果没有存在那么数据可以存在数据库当中。但是来的时候发现有这个数据存在了。说明c2上这个锁之前已经有其他的消费者上过这个锁了,也就是有其他消费者消费了这条消息了。
既然有其他消费者已经消费了,那么c2就不要消费了。
通过分布式锁解决了幂等性的问题。