rocketmq(https://github.com/apache/rocketmq)是一个分布式的消息队列,主要有product, broker,consumer,nameserver组成,提供流量的削峰填谷,异步通知,应用解耦的功能。rocketmq和kafka功能上比较相似,但是在底层架构上还是有很多不同, 比如kafka中每个topic下的每个partition对应一个文件,但是rocketmq中在一个broker上的topic的所有messagequeue都共用一个文件,由此带来的一个问题是在kafka中,当一台broker上的partiton很多的时候,磁盘会退化为随机写,但是在rocketmq上不会有这个问题。 但是两者都存在的一个问题是,consumer的能力没有办法线性扩展,当消息队列中积压消息的时候,不能通过增加机器的数量来扩大消费能力,consumer的数量受制于partiton/messagequeue的数量。
这里主要讲rocketmq四个问题:
- 顺序消息
在发送端可以在调用send方法的时候指定messagequeue, 可以利用key hash的方式,保证相同的key落在同一个messagequeue, 如果要保证全局唯一,整个topic可以只有一个messagequeu。在消费端,rocketmq提供了顺序消费的方法。以上只是在理想情况下唯一,网络抖动,broker切换都有可能导致消息不是顺序,使用时需要注意。 - 事物消息
实现方式类似于2pc
1. product发送half消息到broker
2. product根据broker返回的结果,成功或者失败,决定是否执行本地事物。
3. 执行本地事物,根据本地事物结果,决定向broker发送commit或者rollback。
4. 如果第二步返回,或者第三步提交commit/rollback出现网络问题,broker会回查product, product根据回查决定是否重新提交。 - 消费失败问题
rocketmq通过提交offset的方式来表示是否已经消费,在提交的时候会提交一个本地最小的offset,表示小于此offset的都已消费。 对于消费失败的消息,会提交到重试队列,重试队列在重试16次后,如果还失败,会投递到死信队列。 - 消费者如何获取消息
消费者是通过长连接的方式拉取消息
具体可以参考我的注解版:
https://github.com/zhaoyb/rocketmq