GoMind Hub

MQ

计算机知识思维导图:MQ。网页展示前三层结构,可在线查看完整脑图并下载 GoMind 文件。

2026-08-25

计算机知识学习资料思维导图
## MQ
### MQ
#### 优点
##### 异步
##### 解耦
##### 削峰
#### 缺点
##### 系统可用性降低
##### 系统复杂度提高
##### 一致性问题

> 仅展示前三层结构;请在线查看完整脑图或下载 GoMind 文件。

MQ

MQ
异步
解耦
削峰
优点
提高吞吐量
优点
可用性无保障,queue所在节点宕机数据就丢失
集群内部可能产生大量的数据传输,有数据拉取开销
缺点
普通集群模式(无高可用)
多台机器上启动多个RabbitMQ实例,每个机器启动一个。



你创建的 queue,只会放在一个 RabbitMQ 实例上,但是每个实例都同步 queue 的元数据(元数据可以认为是 queue 的一些配置信息,通过元数据,可以找到 queue 所在实例)。你消费的时候,实际上如果连接到了另外一个实例,那么那个实例会从 queue 所在实例上拉取数据过来。
完整数据存在多个实例中
优点
性能开销较大,消息需要同步到所有机器
无法线性扩展
缺点
镜像集群模式
需要先配置普通集群模式后,在后台新增一个策略,这个策略是镜像集群模式的策略,指定的时候是可以要求数据同步到所有节点的,也可以要求同步到指定数量的节点
RabbitMq
replica副本机制
Kafka
保证高可用
系统可用性降低
系统引入的外部依赖越多,越容易挂掉。

本来你就是 A 系统调用 BCD 三个系统的接口就好了, ABCD 四个系统好好的,没啥问题,你偏加个 MQ 进来,万一 MQ 挂了咋整,MQ 一挂,整套系统崩溃,为此就需要保证MQ高可用
若是写库则可通过判断主键是否存在,不存在则插入,存在则更新。也可以增加唯一键约束
生产者发送消息前记录消息id到redis,消费者消费时去redis查看是否有消费过,没有消费则等消费者消费完成后再从Redis中移除该ID
如何处理重复消费
会降低吞吐量,因为太耗性能
1. 使用事务
就是生产者发送数据之前开启 RabbitMQ 事务channel.txSelect,然后发送消息,如果消息没有成功被 RabbitMQ 接收到,那么生产者会收到异常报错,此时就可以回滚事务channel.txRollback,然后重试发送消息;如果收到了消息,那么可以提交事务channel.txCommit
2. 使用Confirm机制
要确保说写 RabbitMQ 的消息别丢,可以开启 confirm 模式,在生产者那里设置开启 confirm 模式之后,你每次写的消息都会分配一个唯一的 id,然后如果写入了 RabbitMQ 中,RabbitMQ 会给你回传一个 ack 消息,告诉你说这个消息 ok 了。如果 RabbitMQ 没能处理这个消息,会回调你的一个 nack 接口,告诉你这个消息接收失败,你可以重试。而且你可以结合这个机制自己在内存里维护每个消息 id 的状态,如果超过一定时间还没接收到这个消息的回调,那么你可以重发。
1. 生产者弄丢了数据
开启持久化
设置持久化有两个步骤:



1. 创建 queue 的时候将其设置为持久化

这样就可以保证 RabbitMQ 持久化 queue 的元数据,但是它是不会持久化 queue 里的数据的。



2. 第二个是发送消息的时候将消息的 deliveryMode 设置为 2, 就是将消息设置为持久化的,此时 RabbitMQ 就会将消息持久化到磁盘上去。
2. RabbitMq弄丢了数据
关闭自动ACK
3. 消费端弄丢了数据
RabbitMq
kafka
如何处理消息丢失
拆分多个 queue,每个 queue 一个 consumer,就是多一些 queue 而已,确实是麻烦点;或者就一个 queue 但是对应一个 consumer,然后这个 consumer 内部用内存队列做排队,然后分发给底层不同的 worker 来处理。
RabbitMq
一个 topic,一个 partition,一个 consumer,内部单线程消费,单线程吞吐量太低,一般不会用这个
写 N 个内存 queue,具有相同业务规则的数据都到同一个内存 queue;然后对于 N 个线程,每个线程分别消费一个内存 queue 即可,这样就能保证顺序性
Kafka
如何保证消息传递的顺序性
系统复杂度提高
一致性问题
缺点