一、应用场景
- 异步处理,比较耗时又不需要同步的操作可以放入队列中进行传递请求,这样消息的发送方和接收方互不干扰即为解耦
- 广播,一次发送大家共享,减少了冗余的操作
- 流量削峰,一次性有大量请求过来,防止应用崩溃。所有请求全部进入消息队列,消费者逐个处理。
二、消息队列过程
- 客户端连接到消息队列服务器,建立TCP连接也就是connection
- channel是在connection内部创建的逻辑连接,线程将会创建单独的channel进行通讯,而不需要每次都创建一个connection。
- 客户端声明一个exchange,设置相关属性
- 客户端声明一个queue,设置相关属性
- 客户端使用routing key,在exchange和queue之间建立好绑定关系
- 客户端投递消息到exchange
三、有了connection为什么还引入信道channel
- 一个应用中必然有很多生产信息和消费信息,需要建立很多个connection,也就是多个TCP连接。对于操作系统建立和销毁TCP连接开销很大。引入channel复用TCP连接可以减少性能开销
- 当每个channel的流量不是很大时,复用单一的connection可以有效地节省TCP连接资源。但是channel流量很大,多个channel复用一个connection就会产生性能瓶颈。此时需要多个connection,将信道均摊到conenction中。这些调优策略需要根据自身业务情况调节
四、Exchange类型
- fanout:广播式推送消息,生产者只需要把消息推送至fanout exchange中,不需要指定routingkey,exchange绑定的消费者都会接收到消息
- direct:一对一推送消息,当生产者的routingkey和消费者的routingkey完全匹配时,才会推送消息到消费者
- topic:与direct类似,匹配规则为通配符类型
- header:不常用
五、消息幂等性
- 概念:保证同一条消息不会重复或者重复消费了也不会对系统数据造成异常。消息消费完成后向MQ回复一个ack,如果准备ack时系统出问题,没有ack成功。系统重启后会重复消费MQ消息。
- 处理方案:可以给消息加一个唯一Id,根据唯一Id判断消息是否处理过。
六、消息可靠性
- 消息出现丢失情况
1.1 生产者在将数据发送到MQ的时候,可能由于网络等原因造成消息投递失败
1.2 未开启RabbitMQ的持久化,服务挂掉后队列数据丢失
1.3 消费者刚接收到消息还没处理完成,消费者挂掉 - 处理方案
1.1 生产者confirm机制
1.2 queue和消息持久化
1.3 取消自动ack,手动ack,可能出现重复消费消息,保证重复消费幂等性
七、消息顺序性
- 拆分多个queue,一个队列对应一个消费者
参考内容
- https://www.cnblogs.com/lfalex0831/p/8963247.html
- https://blog.csdn.net/qq_34021712/article/details/72567801
- https://www.cnblogs.com/eleven24/p/10326718.html
- https://blog.csdn.net/zw791029369/article/details/109561457
- https://www.cnblogs.com/wffzk/p/13467121.html