MQ----如何保证消息不被重复消费,被重复消费了怎么办

MQ–保证消息不被重复的消费

文章链接地址:
感谢前辈分享
https://github.com/doocs/advanced-java/blob/master/docs/high-concurrency/how-to-ensure-that-messages-are-not-repeatedly-consumed.md
消息的重复消费是我们在使用MQ的时候需要考虑的
那么什么时候能够被重复的消费呢?
比如说:

Kafka有一个offset的概念

,就是每一个消息写进去的时候,都有一个offset,代表消息的序号,然后consumer消费了数据之后,每隔一段时间,就会把消费过度额offset提交一下,表示我已经消费过了,下次我要是重启的话,就继续让我从上次消费的地方消费吧
但是总会出现意外,如果碰到着急的事情直接kiil了线程在重启的时候,有些地方consumer已经将消息处理了,但是还没来的及提交,这个时候重启之后少数的消息会再次消费一次。

其实重复消费不可怕,问题是重复消费之后怎么保证数据的幂等性
假设有一个系统,消费了一条消息就往数据库中插入一条数据,要是一个消息被重复的消费了两次,这样的话就插入了两条信息,这样数据就是错误了,但是如果我们消费第二次的时候自己判断一下是否已经消费过了,若是消费过了之后就直接冷掉,这样就保留了一条数据,从而保证了数据的正确性
通俗的说就是,一个数据或者一个请求,给你重复的来多次,确保其对应的数据不会改变,不能够出错。

怎么保证消息不被重复的消费?

如果要写数据库的话,可以先根据主键查一下,如果这数据都有了,你就别插入了,update 一下好吧。
比如你是写 Redis,那没问题了,反正每次都是 set,天然幂等性。
比如你不是上面两个场景,那做的稍微复杂一点,你需要让生产者发送每条数据的时候,里面加一个全局唯一的 id,类似订单 id 之类的东西,然后你这里消费到了之后,先根据这个 id 去比如 Redis 里查一下,之前消费过吗?如果没有消费过,你就处理,然后这个 id 写 Redis。如果消费过了,那你就别处理了,保证别重复处理相同的消息即可。
比如基于数据库的唯一键来保证重复数据不会重复插入多条。因为有唯一键约束了,重复数据插入只会报错,不会导致数据库中出现脏数据。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值