文章目录
- 一、消息队列对比
- 二、RocketMQ 基础
- 1. 消息模型
- 2. 技术架构
- 3. 消息类型
- 4. 消费者类型
- 5. 消费者分组和生产者分组
- 三、RocketMQ 高级
- 1. 如何解决顺序消费和重复消费
- 2. 如何实现分布式事务
- 3. 如何解决消息堆积问题
- 4. 如何保证高性能读写
- 5. 刷盘机制 (topic 模型)
- 6. 存储机制(topic 模型)
一、消息队列对比
对比方向 | 概要 |
---|---|
吞吐量 | 万级的 ActiveMQ 和 RabbitMQ 的吞吐量(ActiveMQ 的性能最差)要比十万级甚至是百万级的 RocketMQ 和 Kafka 低一个数量级。 |
时效性 | RabbitMQ 基于 Erlang 开发,所以并发能力很强,性能极其好,延时很低,达到微秒级,其他几个都是 ms 级。 |
可用性 | 都可以实现高可用。ActiveMQ 和 RabbitMQ 都是基于主从架构实现高可用性。 |
可靠性 | ActiveMQ 和 RabbitMQ 丢失的可能性非常低, Kafka、RocketMQ 和 Pulsar 理论上可以做到 0 丢失。 |
可扩展性 | Kafka、RabbitMQ 具有良好的可扩展性,可以通过添加更多的节点来提高容量和性能。RocketMQ 支持水平和垂直扩展,但是节点的数量有一定限制。 |
顺序消息 | Kafka 同一分区内保证顺序性、RocketMQ 原生支持顺序消息队列,RabbitMQ 需要使用单个队列实现 |
其他 | 持久化、延迟队列、死信队列、消息回溯、消息确认、消息TTL、消费模式 |
Ref: https://cloud.tencent.com/developer/article/1944357
二、RocketMQ 基础
1. 消息模型
- 队列模型
局限:无法广播
- 主题模型 / 发布订阅模型
Producer Group
、Topic
、Consumer Group
2. 技术架构
3. 消息类型
- 普通消息
- 生命周期:初始化>待消费>消费中>消费提交>消息删除)
- 定时消息(延时 & 定时)
- 生命周期:初始化>定时中>待消费>消费中>消费提交>消息删除
- 顺序消息
- 事务消息
4. 消费者类型
- PushConsumer
- 哪些错误使用方式会导致无法保证消息的可靠性(核心: 必须消费成功再返回)
- SimpleConsumer
- 是一种接口原子型的消费者类型,消息的获取、消费状态提交以及消费重试都是通过消费者业务逻辑主动发起调用完成
- PullConsumer
5. 消费者分组和生产者分组
- 生产者分组是匿名的;
- 消费者分组是多个消费行为一致的消费者的负载均衡分组,可以实现水平扩展以及高可用容灾。
三、RocketMQ 高级
1. 如何解决顺序消费和重复消费
顺序消费
- 只有队列模型支持
- 普通顺序(异常情况下可能乱序,比如 broker 重启)和严格顺序(binlog 同步场景)
- 多队列时需要使用队列选择算法(轮询算法 - 绑定topic & 默认,最小投递延迟 - 会导致消息分布不均匀,继承MessageQueueSelector实现hash)保证同一类数据始终路由到同一队列
重复消费
- 实现幂等
2. 如何实现分布式事务
比较常见的分布式事务实现有 2PC、TCC 和事务消息(half 半消息机制);
RocketMQ 使用 事务消息 + 事务反查机制
以上步骤 都是在生产者监听器实现类中实现的,
- 对应接口:RocketMQLocalTransactionListener,
- 接口方法:
- executeLocalTransaction - 事务执行方法
- checkLocalTransaction - 事务回查方法
事务消息是生产者通过 rocketMQTemplate.sendMessageInTransaction 方法发送的
3. 如何解决消息堆积问题
消息堆积的根源:生产者生产太快 或 消费者消费太慢
- 生产者生产太快:限流降级
- 消费者消费太慢:检查是否有大量消费失败,排查资源死锁
- 通用方案:增加消费者实例数量和每个主题的队列数量
4. 如何保证高性能读写
- 零拷贝技术 vs. 传统 IO(read/write)
mmap(4次上下文切换+3次IO,优点是用户可以感知和修改数据内容,RocketMQ 主要使用的方法) 和 sendfile(2次上下文切换+3次IO)
5. 刷盘机制 (topic 模型)
同步刷盘 & 异步刷盘
- 保证可靠性
同步复制 & 异步复制
- 保证可用性,不影响可靠性,因为主从复制的主节点挂掉后生产者不会再向该队列发送,也不会自动切换主从
6. 存储机制(topic 模型)
RocketMQ 消息存储架构中的三大角色——CommitLog、ConsumeQueue 和 IndexFile
CommitLog
:消息主体以及元数据的存储主体,用于顺序写入日志文件ConsumeQueue
:消息消费队列,引入的目的主要是提高消息消费的性能,ConsumeQueue(逻辑消费队列)作为消费消息的索引,保存了指定 Topic 下的队列消息在 CommitLog 中的起始物理偏移量 offset,消息大小 size 和消息 Tag 的 HashCode 值。Consumequeue 文件可以看成是基于 topic 的 Commitlog 索引文件IndexFile
:IndexFile(索引文件)提供了一种可以通过 key 或时间区间来查询消息的方法