消息重复消费如何解决?
影响消息正常发送和消费的重要原因是网络的不确定性。
出现原因
正常情况下在 consumer 真正消费完消息后应该发送 ack,通知 broker 该消息已正常
消费,从 queue 中剔除
当 ack 因为网络原因无法发送到 broker,broker 会认为词条消息没有被消费,此后会
开启消息重投机制把消息再次投递到 consumer。
消费模式:在 CLUSTERING 模式下,消息在 broker 中会保证相同 group 的 consumer 消
费一次,但是针对不同 group 的 consumer 会推送多次
解决方案
数据库表:处理消息前,使用消息主键在表中带有约束的字段中 insert
Map:单机时可以使用 map 做限制,消费时查询当前消息 id 是不是已经存在
Redis:使用分布式锁。
线上业务用消息中间件的时候,是否需要保证消息的顺序性?
如果不需要保证消息顺序,为什么不需要?假如我有一个场景要保证消息的顺序,你们
应该如何保证?
首先多个 queue 只能保证单个 queue 里的顺序,queue 是典型的 FIFO,天然顺序。
多个 queue 同时消费是无法绝对保证消息的有序性的。所以总结如下:
同一 topic,同一个 QUEUE,发消息的时候一个线程去发送消息,消费的时候 一个线
程去消费一个 queue 里的消息。
追问:怎么保证消息发到同一个 queue?
Rocket MQ 给我们提供了 MessageQueueSelector 接口,可以自己重写里面的接口,
实现自己的算法,举个最简单的例子:判断 i % 2 == 0,那就都放到 queue1 里,否则放
到 queue2 里。