多个 mq 如何选型
-
RocketMQ
- Java 开发
- 集群化,效率高,每秒可解决几十万条音讯
- 有音讯查问界面
- 音讯可靠性高
-
Kafka
- Scala 开发
- 效率高
- 音讯失落概率大,适宜做日志收集、埋点上报等业务
-
RabbitMQ
- erlang 开发
- 对音讯沉积反对不敌对
-
ActiveMQ
- Java 开发,简略、稳固,效率不高
MQ 的作用
-
解耦
- 上游发 mq,上游订阅,上游不须要关怀有哪些上游零碎,不须要与上游间接交互
-
异步
- 不须要同步执行的业务逻辑,异步解决,缩小响应工夫
-
削峰
- 后端 Service 能够放弃固定速率生产,甚至进行生产,保证系统不被压垮
RocketMQ 从生产发送到生产的执行流程
- Producer 发送音讯到 Broker,负载平衡策略默认随机
- Broker 接管音讯,写入 PageCage,返回胜利
- Broker 刷盘,音讯存储 Consumer queue、commit log
- Consumer 从 Broker 拉取音讯,拉取形式长轮询 pull
- Consumer 生产音讯,解决业务逻辑
- Consumer 返回 ACK,更新 Broker offset
- 生产失败,音讯转入失败队列
- Broker 的 ScheduleService 从重试队列拉取音讯,重放这个音讯
- 重试 16 次如果还是失败,音讯进入死信队列
- 通过 RocketMQ 操作面板监控死信队列,手动解决
RocketMQ 如何做负载平衡
Topic 在 Broker 集群中分布式存储
Producer 端:轮询
Consumer 端:平均分配策略,一个队列最多被一个生产组的一个 Consumer 生产,一个 Consumer 能够生产多个队列
RocketMQ 如何保障音讯不失落
1、Producer 端
- 采取 send()同步发消息,发送后果是同步感知的。
- 发送失败后能够重试,设置重试次数。默认 3 次。
producer.setRetryTimesWhenSendFailed(10);
- 集群部署,比方发送失败了的起因可能是以后 Broker 宕机了,重试的时候会发送到其余 Broker 上。
2、Broker 端
- 批改刷盘策略为同步刷盘
- 批改主从复制策略为同步复制
3、Consumer 端
- 生产胜利后会返回 ACK,更新 Broker 的 offset
音讯失落的场景
- 异步刷盘,Broker 宕机,未实现刷盘
- 异步复制,主 Broker 宕机,未实现复制
反复生产问题
1、造成反复生产的起因
- Consumer 生产完,宕机,未返回 ACK
- Consumer 生产完,返回 ACK,网络断开,Broker 未收到
- 主 Broker 更新 ACK,副 Broker 未复制,主 Broker 宕机
2、解决
业务方管制幂等
- 定义业务幂等字段,数据库定义为惟一键
怎么发送程序音讯
- 将音讯发送到同一个队列中
- 通过重写 MessageQueueSelector 接口,将不同的音讯发送到指定的队列
- Consumer 生产的时候如果是多线程,须要先应用 synchronize 获取锁
- 一条音讯生产失败,将阻塞整个队列,所以个别不必
RocketMQ 效率高的起因
- 分区并行。每个 Topic 能够设置多个 MessageQueue(Partition),能够对应多个消费者实现并行处理
- 程序写磁盘。对 commit log 采纳追加写的形式,新音讯被追加到文件的末端
- 利用页缓存 PageCache。Broker 收到数据后,写入 PageCache 即算胜利,由操作系统本人管制刷盘
- 零拷贝。消费者能够间接从 PageCache 读取数据,缩小了数据复制次数,防止了用户态与内核态之间的切换
- 应用 Netty 框架实现高性能的网络传输
RocketMQ 与 Kafka 的异同
1、定位
- Kafka 定位高吞吐,对音讯反复、失落没严格要求,实用数据量超大的日志收集、埋点数据收集等常见
- RocketMQ 思路源于 Kafka,提供了更牢靠的音讯传输,具备高吞吐、高可用个性,实用大规模分布式系统利用
2、单机反对队列数
- Kafka 队列数超过 64 个性能会降落,对多个 Partition 文件的程序写在操作系统层面变成了随机写
- RocketMQ 队列数增多效率无显著降落,因为数据存储在一个 commit log
3、数据可靠性
- Kafka 应用异步刷盘,异步主从复制,Producer 只反对异步发送音讯,且会积攒一批音讯一起发
- RocketMQ 反对同步刷盘,同步主从复制,Producer 发送音讯反对同步、异步、单向三种模式
4、过后音讯
- Kafka 不反对
- RocketMQ 反对 level 级别的定时音讯
5、音讯失败重试
- Kafka 不反对
- RocketMQ 反对工夫 level 级别的重试
以下 RocketMQ 反对,Kafka 不反对:
6、分布式事务音讯
7、程序音讯
8、音讯查问
9、音讯回溯
RocketMQ 音讯底层存储模型
- CommitLog 存储真正的音讯体
- ConsumerQueue 是 CommitLog 的索引文件,存储音讯在 CommitLog 的物理偏移量,音讯大小,tag 的 hashCode
- IndexFile 是面板查问的索引文件
定时音讯实现原理
- 提早级别大于 0 示意提早音讯,将音讯转存到 SCHEDULE_TOPIC_XXX 队列
- ScheduleService 定时工作拉取延时队列中的音讯(未到延时工夫则提早 100 毫秒再拉)
- 依据偏移量从 CommitLog 拉取音讯体
- 复原成原来的音讯主题,将音讯投递到原主题队列
音讯沉积如何解决
1、减少 Consumer,减少 MessageQueue,减少 Consumer 线程数
2、新建一个 Topic,先生产将音讯搬运到另外一个 Topic,后用新 Consumer 生产解决
分布式事务音讯实现原理
Half Message:预处理音讯,当 broker 收到此类音讯后,会存储到 RMQ_SYS_TRANS_HALF_TOPIC 的音讯生产队列中
查看事务状态:Broker 会开启一个定时工作,生产 RMQ_SYS_TRANS_HALF_TOPIC 队列中的音讯,每次执行工作会向音讯发送者确认事务执行状态(提交、回滚、未知),如果是未知,Broker 会定时去回调在从新查看。
超时:如果超过回查次数,默认回滚音讯。
也就是他并未真正进入 Topic 的 queue,而是用了长期 queue 来放所谓的 half message,等提交事务后才会真正的将 half message 转移到 topic 下的 queue。
其余
RocketMQ 生产模式有几种?
生产模型由 Consumer 决定,生产维度为 Topic。
- 集群生产
1. 一条音讯只会被同 Group 中的一个 Consumer 生产
2. 多个 Group 同时生产一个 Topic 时,每个 Group 都会有一个 Consumer 生产到数据
- 播送生产
音讯将对一 个 Consumer Group 下的各个 Consumer 实例都生产一遍。即即便这些 Consumer 属于同一个 Consumer Group,音讯也会被 Consumer Group 中的每个 Consumer 都生产一次。
如果让你来入手实现一个分布式消息中间件,整体架构你会如何设计实现?
- 反对集群,反对疾速扩容
- 音讯存储模型
- 高性能
- 高可用性
- 数据 0 失落的思考