消息投递分为两个部分,一是生产者对Broker的消息投递,二是Broker对消费者的消息投递。 生产者需要保证消息正确的投递到了Broker, Broker保证每个消息至少消费一次。
RabbitMQ
1.事务(同步,性能差)
txSelect() //事务开启
txCommit() //事务提交
txrollback() //事务回滚
2.confirm 确认机制,包含三种模式
普通确认:发送完一条消息,就等待waitForConfirms方法,等待Broker返回
批量确认:发送完一批消息之后,等待waitFormConfirms,(异常情况下,会导致大量消息重复,会带来重复消息)
异步确认:注册回调,Broker确认了一条或多条之后,执行回调
3.消费的消息确认包括三种模式
autocommit 自动提交(在消息处理失败的情况下,会丢失消息),
手动ACK
NACK (消息会重会队列)
4.消费确认过程
(1)broker投递消息给消费者,并将投递的消息记录为已投递未确认。
(2)消费者消费消息,并根据ACK模式进行消息消费确认(手动、自动)
(3)如果消费者提交ACK,broker将对应消息标记删除,并等待被删除
(4)如果提交NACK,将该消息重新投递到消费队列中。
(5)如果已投递未确认的消息在指定时间内未收到消息确认,重新投递到消息队列中。
参考:https://blog.csdn.net/u013256816/article/details/55515234/
RocketMQ
1.rocketMQ事务消息流程
(1)发送half消息,消息状态为half状态,消费者看不见(确认MQ还活着,且将消息发送的半消息队列)
(2)执行本地任务
(3)如果本任务执行失败 rollback MQ删除half消息
(4)否则commit,将half消息标记为已提交,并将消息投递的消费队列中。
2.事务补偿流程,对一直没有进行commit/rollback的消息,回调你的系统接口。
3.底层原理
(1)如果发现是half消息,会把消息写入 RMQ_SYS_TRANS_HALF_TOPIC 这个topic对应的一个ConsumeQueue 里去,所以消费者无法看见。
(2)补偿机制是后台有个定时任务,去扫描RMQ_SYS_TRANS_HALF_TOPIC中的half消息,如果超过一定时间还是half消息,会调用指定接口,去判断这个half消息是rollback 或 commit。
(3)RocketMQ都是顺序写入磁盘文件的,rollback的时候,本质是用一个OP操作标记消息的状态。如果commit,RocketMQ就会在OP_TOPIC里写一条记录,标记half消息commit,同时将消息写入对应的Topic的ConsumeQueue里。
4.消费确认
(1)与RabbitMQ不同,RocketMQ ACK之后,并不会删除消息,只是提交消费进度。当返回NACK时,会进入重试队列(并发模式下)
(2)默认重试次数最多16次,时间间隔每次不一样,可以进行配置 messageDelayLevel=1s 5s 10s 30s 1m 2m .....
(3)如果16次都无法处理完成,这时候就需要一个队列叫做 死信队列。
(4)我们可以单独对死信队列的消息进行单独处理,比如单独开一个后台线程,进行订阅处理。
Kafka
1.消息事务
确保一个事务中发送的多条消息,要么都成功,要么都失败,没有反查机制。Kafka的这种事务机制,单独来使用的场景不多,更多的情况下是被用来配合Kafka幂等进制来实现Kafka的 Exactly Once。
通常理解消费队列的Exactly Once,是指消息从生产者发送到Broker,然后消费者从Broker拉取消息,进行消费,这个过程确保每个消息恰好传输一次,不重不丢。
Kafka解决的是在流计算中,用Kafka作为数据源,并且将计算结果保存到Kafa这种场景下,数据从Kafka的某个主题中消费,在计算集群中计算,在把计算结果保存在Kafka的其他主题中。这样的过程中,保证每条消息恰好计算一次,确保计算结果正确。
Kafka的 Exactly Once 机制,是为了解决 读数据-计算-保存结果 这样的计算过程中的数据不重不丢。
2.消费确认:
这里消费确认是指提交消费位移,与RocketMQ相似,但是Kafka不支持重试。
总结
1.RabbitMQ提供事务及confirm机制实现生产者的投递保证,并通过消费确认机制实现消费者至少消费一次。
2.RocketMQ通过half消息即事务补偿流程实现生产者投递的保证。消费确认ACK并不会删除消息,只是提交消费进度。NACK时,消息会进入重试队列。
3.Kafka通过事务机制实现生产者的投递保证,消费者在确认消费时提交消费位移。
参考
1.狸猫技术窝 RocketMQ系列
2.《深入理解Kafka:核心设计与实践原理》
3.《RabbitMQ实战》