整理自 adjava.netlify.app/#/./docs/hi…
GitHub: github.com/KinghooWei/… 含PDF文件和XMind文件
转载注明出处:juejin.cn/post/693873…
消息队列
使用场景
解耦
- 发布订阅消息模型
异步
- 处理耗时操作
削峰
- 高并发
种类
ActiveMQ
RabbitMQ
- 延迟低
RocketMQ
Kafka
缺点
系统可用性降低
系统复杂度提高
一致性问题
高可用
RabbitMQ
- 单机模式
- 普通集群模式
- 镜像集群模式
Kafka
-
分布式架构:创建topic,划分为多个partition,每个partition放一部分数据,存在于不同的broker上
-
副本机制:将partition的所有replica分布在不同机器上,通过leader读和写
- 写:消费者写leader,leader写本地磁盘,follower主动从leader中pull数据,所有follower同步完成后发送ack给leader,leader返回写成功信息给消费者
- 读:leader收到ack后,才能被消费者读到
设计MQ
参照Kafka,分布式架构,可扩展,增加吞吐量
落地磁盘,顺序写,没有磁盘随机读写的寻址开销
高可用,多副本
数据0丢失
幂等性
场景:消费者还没来得及提交offset,就发生重启
方案
- 数据库:设置主键,防止出现脏数据;insert之前先查,有则update
- Redis:天然幂等
- 生产者发送的数据加一个全局唯一id,每次消费根据id查询Redis,有则丢弃,没则写Redis并处理
可靠性传输
Kafka
-
消费者:消费者提交了offset,但没来得及处理就挂了
- 可以先处理再提交offset,但要注意幂等性问题
-
Kafka:follower还没同步好数据,leader就挂了
- partition至少有2个follower
- 至少有1个follower跟leader保持联系
- 数据写入所有follower,生产者才认为写成功
- 一旦写入失败,无限重试
RabbitMQ
-
生产者
- 事务机制
- confirm机制
-
RabiitMQ
- 持久化结合生产者的confirm机制
-
消费者
- 关闭RabbitMQ自动ack
顺序性
Kafca
-
消费者开多线程处理数据破坏顺序性
- 消费之写N个内存queue,具有相同key的数据都到同一个内存queue,对于N个线程,每个线程分别消费一个内存queue
RabbitMQ
-
多个消费者消费数据,处理时破坏了顺序性
- 拆分多个queue,每个queue一个consumer
消息积压
修复消费者,暂停运行现有消费者
新建topic,partition是原来的10倍
写一个分发数据的消费者程序
临时征用10倍的机器部署消费者
RocketMQ
- 提高消费并行度
- 批量方式消费
- 跳过非重要消费
- 优化每条消息消费过程