概览
- RocketMQ 官方文档: https://rocketmq.apache.org/docs/quick-start/
- RocketMQ 中国开发者中心:http://rocketmq.cloud/zh-cn/
- Kafka 官方文档: http://kafka.apache.org/documentation/
- RabbitMQ 官方文档: https://www.rabbitmq.com/documentation.html
消息队列作用场景
- 异步处理
- 流量控制
- 服务解耦
- 作为发布 / 订阅系统实现一个微服务级系统间的观察者模式
- 连接流计算任务和数据
- 用于将消息广播给大量接收者
RabbitMQ, RocketMQ, Kafka, Pulsar对比
选择中间件的考量维度:可靠性,性能,功能,可运维行,可拓展性,是否开源及社区活跃度
rabbitmq:
优点:轻量,迅捷,容易部署和使用,拥有灵活的路由配置
缺点:性能和吞吐量较差,不易进行二次开发
rocketmq:
优点:性能好,稳定可靠,有活跃的中文社区,特点响应快
缺点:兼容性较差,但随意影响力的扩大,该问题会有改善
kafka:
优点:拥有强大的性能及吞吐量,兼容性很好
缺点:由于“攒一波再处理”导致延迟比较高
pulsar:
采用存储和计算分离的设计,是消息队里产品中黑马,值得持续关注
主题和队列
工作队列模型
发布订阅模型
在rabbitmq中, 一个交换机, 可以连多个队列, 每个队列可以有多个消费者
在rocketmq中,
- 可以有多个队列, 生产者发布的每条消息只会进其中一个队列, 主题并不能保证有序
- 可以有多个消费组, 一个队列中的一条消息会被每个消费组消费, 因此队列也会维护每个消费组消费的位置, 队列中的消息是有序的
- 一个消费组中可以有多个消费者, 一条消息只能被某个消费者消费一次
在kafka中, 架构同rocketmq, 只不过队列对应的概念是分区
RocketMQ的分布式事务实现
如何确保消息不会丢失?
可以在发送端添加拦截器, 给每条消息添加个顺序递增的序号;
然后在消费端添加拦截器, 验证序号的连续性, 即可排查到是否有消息丢失
如何确保消息不丢失?
- 在生产阶段,你需要捕获消息发送的错误,并重发消息。
- 在存储阶段,你可以通过配置刷盘和复制相关的参数,让消息写入到多个副本的磁盘上,来确保消息不会因为某个 Broker 宕机或者磁盘损坏而丢失。
- 在消费阶段,你需要在处理完全部消费业务逻辑之后,再发送消费确认。
如何保证幂等性
- 利用数据库等添加唯一约束条件
比如转账操作, 需要先添加记录, 再添加余额, 在添加记录时设置业务关联的编码的唯一约束, 防止重复添加, 也就不会多次加余额
- 设置前提条件
比如CAS操作, 需先判断条件再操作
- 记录并检查操作
给消息指定全局唯一id, 消费时先判断消息是否被消费过, 但要注意”检查消费状态,然后更新数据并且设置消费状态”三个操作必须作为一组操作保证原子性,才能真正实现幂等