RocketMQ常见问题-消息重复消费和消息重复的问题

RocketMQ不解决消息重复问题,RocketMQ不解决消息重复问题,RocketMQ不解决消息重复问题,重要的事情说三遍。
基本上说我很讨厌有人问这个问题,问这个问题首先你对消息的生命周期缺乏理解,其次RocketMQ的定位不是很清楚,RocketMQ单机写入TPS单实例约7万条/秒,单机部署3个Broker,可以跑到最高12万条/秒,消息大小10个字节。换句话说单机RocketMQ的每分钟处理的请求是12W*60=720W,每小时处理的请求是720W*60=44400W。在这么大的信息量面前任何额外的要求不觉得都有点吹毛求疵。(所以如果有人坚持去要求你从RocketMQ的角度解决消息重复消费问题,你可以开始撕逼模式了。)

       然而消息重复的问题确实存在,我们该如何解决呢。
       消息的生命周期包括分为消息产生源,消息传播(消息发送,消息投递,消息消费),消息持久化这几个环节。在使用RocketMQ过程中,RocketMQ主要负责消息发送,消息的传递,消息消费的问题,然而RocketMQ解决不了消息重复消费的问题,实际上RocketMQ还有消息重复发送和消息重复投递的问题。
1.1 生产者重发导致相同
        由于网络闪断或者客户端宕机,导致服务端对客户端应答失败。此时如果生产者再次发送消息,消费者就会出现内容相同并且MessageID也相同的消息。
1.2服务端重推导致相同
        当客户端给服务端反馈应答的时候网络闪断或者客户端消费完成反馈前宕机,服务端会在网络恢复后重发一次。
上面两条是RocketMQ本身存在的MessageID相同的问题,之前也有人说通过业务key来保证消息是不重复的。
1.3消费者解决不了重复消费
       RocketMQ是分布式环境,消息系统自身解决消费重复问题,需要消费者端进行大量的确认。一方面这种确认会导致大量消息阻塞,另一方面分布式环节下需要网络确认,消息在网络传递过程中具有不可靠性。

     事实证明消息的传递具有不可靠性;网络不可靠性,只要通过网络传输的消息都具有网络不可靠性;或者说系统受到黑客的恶意篡改,导致的消息完全一致等等。只要消息经过传递,希望在传递层保证消息都无法100%保证消息的可靠性。传递过程无法确保消息不重复,那么消息源也就不需要关注了,因为即使消息源确保唯一,传递过程中还是会产生重复消息。 

       消息流从五个环节从消息源,消息发送,消息传递,消息消费都无法保证消息不重复,那么我们能做的只有在消息持久化环节保证消息不重复。其实所有的保证消息不重复的策略都需要一个消息持久化的位置供消息重复验证,然而不巧的是除非和消息最本源的位置做验证,其他环节的验证都具有不可靠性。
消息持久层做消息唯一性的策略
       1.持久化过程中业务唯一标识验证,每个消息具有业务唯一标识,在消息最终持久化之前通过验证唯一性标识保证消息的唯一性。消息持久化位置如果出现同样的消息,系统就不做处理,期间无任何传递过程,保证消息的唯一性。
       2.使用过程中业务唯一标识验证,使用过程中如果出现同样的消息,系统进行相应的异常处理。

备注:例如mysql去重表

总结:
消息的生命周期中只有在消息产生源和消息持久源才是具有意义的,在过程中不必太苛求。

你可能感兴趣的:(RocketMQ)