Basic
Concept
- topic:主题,实现发布订阅功能
- queue:队列,实现负载均衡功能
- partition:分区,实现并发处理功能
ps:partition和queue的作用类似,但partition的抽象度更高
Protocol
TMQP
TMQP(Topical Message Queuing Protocol):主题消息队列协议
- 基于主题(Topic)的消息队列协议
- 基于生产和消费模式,支持主题分区
- 功能较弱,但性能强大,适合数据量大的业务场景
常见的组件有Kafka、RocketMQ
RocketMQ是Kafka和RabbitMQ的混合体,性能较高(能支持较大的数据量),且功能较丰富
ps:TMQP是我自己取的名字,方便和其他协议对照说明问题
AMQP
AMQP(Advanced Message Queuing Protocol):高级消息队列协议
- 基于交换机(Exchange)的消息队列协议
- 基于生产和消费模式,支持路由匹配
- 功能强大,但性能较差,适合数据量小的业务场景
常见的组件有RabbitMQ
MQTT
MQTT(Message Queuing Telemetry Transport):消息队列遥测传输协议
- 基于主题(Topic)的消息队列协议
- 基于发布和订阅模式,支持传输质量控制(Qos)
- 协议比较简单轻量,适合物联网(IOT)相关的业务场景
MQTT和WebSocket对比
- MQTT是消息传输协议,WebSocket时报文传输协议
- WebSocket比较简单,除了传递报文的功能,就没有其他核心的功能了
- MQTT比较复杂,除了传递消息的功能,还支持消息的发布和订阅以及消息传输质量的控制
ps:MQTT可以基于Socket(Tcp)实现,也可以基于WebSocket实现
物联网通信的数据格式
- xml
- json
- bin
- Hessian(比较早期的框架)
- MessagePack(Json格式的优化版)
- Protobuf(Google出品的框架)
- Thrift(FaceBook出品的框架)
- Avro(Hadoop的一个子项目)
- Kyro(针对java的二进制协议)
- Fct(针对java的二进制协议)
Middleware
RabbitMQ
Basic
Concept
Exchange
交换机类型
- 定向交换机(单播):Direct(bindingKey和routingKey进行等值匹配)
- 主题交换机(组播):Topic (bindingKey和routingKey进行模糊匹配)
- 扇出交换机(广播):Fanout(bindingKey和routingKey都会被忽略掉)
- Header交换机:对消息和队列的header进行等值匹配(支持匹配全部或者任意一个header)
- 默认交换机:每个队列创建时都会以队列名称为bindingKey绑定到默认交换机
ps:如果发送消息时不指定交换机,就会发送到默认交换机上,此时routingKey应该为队列名称
Consumer
Manage
RocketMQ
Basic
Concept
Topic
Consumer
Manage
Kafka
Basic
Concept
Topic
Consumer
Config
Tools
Manage
ZeroMQ
基于消息队列的多线程网络库
ActiveMQ
不常用
ActiveMQ是老牌的消息队列协议,性能较差
Disque
不常用
Disque是redis作者开源的内存队列
Usage
消息延时
延迟时间:TTD(Time To Delay)
RabbitMQ
RabbitMQ原生 不支持
消息延时,但可以用以下方式来实现延时功能
- 死信队列
- 延时插件
RocketMQ
RocketMQ原生 支持
消息延时
Kafka
Kafka原生 不支持
消息延时
消息过期
存活时间:TTL(Time To Live)
RabbitMQ
RabbitMQ原生 支持
消息过期 ,还支持为队列里面的消息统一设置过期时间
RocketMQ
RocketMQ原生 不支持
消息过期 ,但可以通过在消费端判断 当前时间
和 消息产生时间
的差值来实现
Kafka
Kafka原生 不支持
消息过期 ,但可以通过在消费端判断 当前时间
和 消息时间戳
的差值来实现
消费策略
MQ消费策略
- 按照消费模式分
- 集群模式:独占消息
- 广播模式:共享消息
- 按照消费顺序分
- 串行消费:单个消费者
- 并行消费:多个消费者
- 按照消费数量分
- 单条消费:一次取一条
- 批量消费:一次取多条
集群消费模式的分配策略
- 轮询(round-robin)
- 分键(key-sharding)
- 哈希分区(hash)
- 粘性分区(sticky)
RabbitMQ
- 简单队列:
- 工作队列:相当于集群模式
- 发布订阅:相当于广播模式
- 直接匹配:相当于分区模式
- 通配匹配:相当于分区模式
RocketMQ
Kafka
消费反馈
- ack:确认(消费成功,可以删除)
- retry:重试(消费失败,需要重试)
- discard:丢弃(消费失败,可以丢弃)
RabbitMQ
RocketMQ
Kafka
分组消费
- 同一组:集群模式(独占消息)
- 不同组:广播模式(共享消息)
ps:分组消费又叫多路消费
RabbitMQ
RabbitMQ原生 不支持分组消费
, 但可以通过扇出交换机广播到多个队列(每个队列是一个分组,绑定了多个消费者)来实现
RocketMQ
RocketMQ原生 支持分组消费
Kafka
Kafka原生 支持分组消费
分区消费
RabbitMQ
RocketMQ
Kafka
死信队列
RabbitMQ
RabbitMQ原生 支持死信队列
RocketMQ
RocketMQ原生 支持死信队列
Kafka
Kafka原生 不支持死信队列
传输模式
生产端:只有推模式
消费端:支持拉模式和推模式
RabbitMQ
RocketMQ
Kafka
控制参数
RabbitMQ
RocketMQ
Kafka
Reliability
Reliability(可靠性)
可靠性的关键点
- 传输
- 确认机制
- 重试机制
- 超时重试
- 异常重试
- 存储(持久化)
- 写盘策略
- 刷盘策略
- 同步策略(主从同步策略)
可靠性的保证
- 生产端:使用确认机制
- 同步发送:同步发送并ACK(sync)
- 异步发送:异步发送并ACK(async)
- 单向发送:异步发送且不ACK(oneway)
- 队列端:开启持久化机制(刷盘策略 + 主从同步策略)
- 写盘策略:
- 同步写盘:写到磁盘后才返回ACK
- 异步写盘:写到页缓存后就返回ACK
- 刷盘策略:
- 每次刷盘
- 每秒刷盘
- 系统刷盘
- 同步策略:
- 不同步:不需要同步到从节点
- 半同步:至少需要同步到一个从节点
- 全同步:需要同步到所有的从节点
- 写盘策略:
- 消费端:使用手动确认机制(不使用自动确认机制)
- 不确认:收到消息后不需要确认
- 自动确认:收到消息后先确认再消费
- 手动确认:收到消息后先消费再确认
RabbitMQ
- 生产端:使用确认机制(使用confirm机制)
- 队列端:开启持久化机制(交换机、队列、消息)
- 消费端:使用手动确认机制(basicAck)
ps:生产端建议使用确认(confirm)机制,不建议使用事务(transaction)机制
ps:确认机制是异步操作,性能好
ps:事务机制是同步操作,性能差
RocketMQ
- 生产端:使用确认机制(使用异步发送)
- 队列端:开启持久化机制(同步刷盘策略 + 同步主从同步策略)
- 消费端:使用手动确认机制(ConsumeStatus)
ps:生产端建议使用异步发送,而不是同步发送和单向发送
ps:异步发送是异步操作,性能好
ps:同步发送是同步操作,性能差
ps:单向发送无确认机制,会丢失消息
Kafka
- 生产端:使用确认机制(生产者的acks配置为1)
- 队列端:开启持久化机制(同步刷盘策略 + 同步主从同步策略)
- 消费端:使用手动确认机制(手动提交offset)
ps:acks含义 0:不关心结果 1:只需主节点写完成 -1:所有从节点都同步完成
Ack(确认机制)
RabbitMQ
RocketMQ
Kafka
Retry(重试机制)
RabbitMQ
RocketMQ
Kafka
Timeout(超时问题)
RabbitMQ
RocketMQ
Kafka
Quality(传输质量)
MQ传输质量
- 最多一次:at most once(会导致消息丢失的问题)
- 最少一次:at least once(会导致消息重复的问题)
- 精确一次:exactly once(需要进行幂等处理)
MQTT传输质量
- Qos-0:最多一次
- 消息发送
- PUBLISH:发送者
- 消息丢失
- PUBLISH:丢失了发送者不会重发
- 消息发送
- Qos-1:最少一次
- 消息发送
- PUBLISH:发送者
- PUBACK:接收者
- 消息丢失
- PUBLISH:丢失了发送者会重发PUBLISH
- PUBACK:丢失了发送者会重发PUBLISH
- 消息发送
- Qos-2:精确一次
- 消息发送
- PUBLISH:发送者
- PUBREC:接收者
- PUBREL:发送者
- PUBCOMP:接收者
- 消息丢失
- PUBLISH:丢失了发送者会重发PUBLISH
- PUBREC:丢失了发送者会重发PUBLISH
- PUBREL:丢失了发送者会重发PUBREL
- PUBCOMP:丢失了发送者会重发PUBREL
- 消息发送
ps:发送者会重发消息,接收者不会重发消息
MQTT消息说明
- PUBLISH:发送者发送了数据消息
- PUBACK:接收者收到了数据消息
- PUBREC:接收者收到了数据消息,告知发送者可以删除用来重发的数据消息缓存
- PUBREL:发送者发送了释放消息,告知接收者可以删除用来去重的数据消息缓存
- PUBCOMP:接收者收到了释放消息,告知发送者可以删除用来重发的释放消息缓存
ps:ACK -> acknowledge,REC -> received,REL -> release,COMP -> complete
RabbitMQ
RocketMQ
Kafka
Durability(持久化)
RabbitMQ
RocketMQ
Kafka
Problem
消息丢失
问题描述:消息丢失
解决办法:确认机制 + 重试机制 + 持久化机制
- 生产时丢失
- 场景1
- 丢失原因:使用自动确认机制时,网络有问题导致生产端发送消息失败
- 解决办法:使用重试机制
- 场景2
- 丢失原因:使用自动确认机制时,网络有问题导致队列端返回ACK失败
- 解决办法:使用重试机制
- 场景3
- 丢失原因:使用自动确认机制时,队列端处理异常导致生产端发送消息失败
- 解决办法:使用重试机制
- 场景1
- 入队时丢失
- 场景1
- 丢失原因:队列端服务强停时,消息还在内存缓冲区中没有持久化到磁盘
- 解决办法:开启持久化机制
- 场景2
- 丢失原因:队列端服务崩溃时,消息还在内存缓冲区中没有持久化到磁盘
- 解决办法:开启持久化机制
- 场景3
- 丢失原因:队列端机器宕机时,消息还在内存缓冲区中没有持久化到磁盘
- 解决办法:开启持久化机制
- 场景1
- 消费时丢失
- 场景1
- 丢失原因:使用手动确认机制时,消费端收到消息后忘记了返回ACK
- 解决办法:需要返回ACK
- 场景2
- 丢失原因:使用自动确认机制时,消费端收到消息后不管是否处理成功就返回了ACK
- 解决办法:需要在处理成功后返回ACK
- 场景3
- 丢失原因:使用手动确认机制时,消费端收到消息后使用了异步处理并立即返回了ACK
- 解决办法:需要在异步处理成功后返回ACK
- 场景1
RabbitMQ
RocketMQ
Kafka
消息重复
问题描述:消息重复
解决办法:幂等处理(数据库唯一性去重 或者 redis的setnx去重)
- 生产时重复
- 场景1
- 重复原因:生产时,队列端回复的ACK丢失了,生产端没有收到ACK会重发
- 解决办法:队列端进行幂等处理
- 场景1
- 消费时重复
- 场景1
- 重复原因:消费时,消费端回复的ACK丢失了,队列端没有收到ACK会重推
- 解决办法:消费端进行幂等处理
- 场景1
ps:反正最后都需要在消费端解决一下,所以只需要在消费端解决就行了
RabbitMQ
RocketMQ
Kafka
消息乱序
问题描述:消息乱序
解决办法:分区有序
- 生产时乱序
- 场景1
- 乱序原因:因为网络的复杂性,先生产的消息可能因发送时间长而后到达
- 解决办法:
- 场景2
- 乱序原因:因为消息的大小不同,先生产的消息可能因发送时间长而后到达
- 解决办法:
- 场景1
- 消费时乱序
- 场景1
- 乱序原因:存在多分区时,消息投递到了消息积压多的分区,导致比后面的消息晚消费
- 解决办法:生产时保证分区有序 或者 只创建一个分区
- 场景2
- 乱序原因:存在多分区时,先消费的消息可能晚于后消费的消息完成
- 解决办法:
- 场景1
ps:总结为3种原因,1. 先发送但后到达 2. 先到达但后消费 3. 先消费但后完成
RabbitMQ
RocketMQ
Kafka
消息积压
问题描述:消息积压
解决办法:需要提高消费速度(增加消费者)
拉模式
时消息会积压在队列端
推模式
时消息会积压在消费端
ps:当消费者数量大于分区数量时,多余的消费者也没活干,这时增加消费者也没用,这时候就需要新建一个分区更多的Topic,并启动一个
数据迁移消费者
将旧Topic迁移到新Topic中,然后增加消费者消费新的Topic
RabbitMQ
RocketMQ
Kafka
消息溢出
问题描述:消息溢出
解决办法:需要抑制生产速度(阻塞生产者)
RabbitMQ
RocketMQ
Kafka
Performance
Kafka为什么这么快
- 顺序读写:寻址快
- 分区读写:并发读写
- 批量读写:减少网络耗时
- 数据压缩:减少数据量从而减少读写时间和传输时间
- 页缓存:避免实时写磁盘的慢操作
- 零拷贝:避免多次拷贝造成的时间浪费
Architecture
Replication
Cluster
Distributed
Application
Theory
Other
Management
管理
Visual
Tools
Operation
运维