本文主要对几种常见消息队列MQ(ActiveMQ、Kafka、RocketMQ、RabbitMQ)的实现机制和使用场景进行了总结。

MQ思维导图

1. ActiveMQ

1.1. 常用操作
1.1.1. 获取消息方式


  • 优点
    可以尽可能快的发送给消费者
    缺点
    消费者缓冲区可能溢出


  • 优点
    不会造成缓冲区溢出
    缺点
    有一点延迟

1.2. 架构
主从架构

1.3. 劣势
吞吐量不足

2. Kafka

2.1. 背景
其他中间件消息处理速度较慢,不支持横向扩展

2.2. 目标

2.3. 优势
高吞吐量
便于横向扩容

2.4. 劣势
不支持JMS协议
多Topic的时候性能较差
如果分区数量过多,会同时对多个分区进行读写,这个时候性能就会不太好
一个分区只能有一个消费者

2.5. 应用场景
日志采集
实时数据计算

2.6. 核心组件
Broker
Producer
Consumer
ZK

2.7. 底层原理
2.7.1. 高吞吐量
Topic换分为多个Partition,提高并发度
充分利用了磁盘顺序读写的性能
使用Zero-Copy技术
直接在内核态进行数据传输,避免拷贝数据导致内核态和用户态的切换
数据批量发送
数据批量压缩

2.7.2. 高查找效率
根据offset为key建立稀疏索引
稀疏索引可以使得索引文档非常小,但是增加了查找消息的时间

2.8. 对比
2.8.1. MQ
不支持JMS协议

3. RocketMQ

3.1. 背景
起源于Kafka,但不是Kafka的一个拷贝
Kafka多Topic的时候性能比较差
对Kafka可靠性传输、事务性做了优化

3.2. 核心组件
NameServer
Broker
Master
Slave
Producer
Consumer

3.3. 优势

  • 有线程的管理台界面,便于管理,且可以看到消息的内容

  • 支持通过Tag,Message Header,Message Body进行过滤

  • 便于横向扩展

  • 数据与索引分开存储

  • 同时支持推和拉

  • 多Topic的时候性能好

  • 原因
    一个Broker共用一个分区,一个分区支持上万队列

  • 支持事务发送
    LocalTransactionExecuter
    TransactionCheckListener
    RocketMQ从4.3版本开始支持事务,原理为先预提交消息,然后执行本地事务,执行成功正式commit消息,如果没成功commit,会不断的check,check超时则回退本地事务
    参考:https://www.infoq.cn/article/2018/08/rocketmq-4.3-release

3.4. 劣势
吞吐量没有kafka高

3.5. 底层原理
3.5.1. 高吞吐量
Topic划分为多个分区,提高并发度
充分利用磁盘顺序读写的性能
使用Zero-Copy技术
直接在内核态进行数据传输,避免拷贝数据导致内核态和用户态的切换
数据批量发送
数据批量压缩

3.5.2. 主从同步
同步双写
异步复制

3.6. 应用场景
电商

3.7. 常用操作

3.8. 和Kafka的比较
3.8.1. 吞吐量
kafka > rocketmq
3.8.2. 数据可靠性
都支持异步/同步刷盘,但kafka同步刷盘的情况下,性能急剧下降
3.8.3. 顺序消费
都支持顺序消费,但kafka在节点宕机的情况下不能保证消息的顺序性

  • 原因
    异步复制

4. RabbitMQ

4.1. 优势
时延低
社区比较稳定

5. 常识

5.1. 主要作用
异步
削峰
解耦

5.2. 如何保证消息的可靠性?

  • Broker
    保证多个replica都写入成功了才算写入成功
  • 生产者
    开启失败不断重试
  • 消费者
    不自动提交,消费成功了再自动提交

5.3. 如何保证消息消费的幂等性?

  • 数据库upset
  • redis set
  • 记录到redis里面,消费前先查询redis

5.4. 如何处理消息挤压?

  • 写一个临时消费者用数据库之类的持久化工具存起来
  • 消费者扩容,如果分区设置相对比较小,对kafka没有效果
Contents
  1. 1. 1. ActiveMQ
  2. 2. 2. Kafka
  3. 3. 3. RocketMQ
  4. 4. 4. RabbitMQ
  5. 5. 5. 常识