1.RabbitMQ的简介
MQ全称是Message Queue,可以理解为消息队列的意思,简单来说就是消息以管道的方式进行传递。
RabbitMQ是一个实现了AMQP(Advanced Message Queuing Protocol)高级消息队列协议的消息队列服务,用Erlang语言的。
2.RabbitMQ的应用场景(https://www.cnblogs.com/hobelee/p/15730610.html)
(1)异步提速
(2)削峰填谷
(3)应用解耦
3.为什么选择RabbitMQ?
(1)除了Qpid,RabbitMQ是唯一一个实现了AMQP标准的消息服务器;
(2)可靠性,RabbitMQ的持久化支持,保证了消息的稳定性;
(3)高并发,RabbitMQ使用了Erlang开发语言,Erlang是为电话交换机开发的语言,天生自带高并发光环,和高可用特性;
(4)集群部署简单,正是应为Erlang使得RabbitMQ集群部署变的超级简单;
(5)社区活跃度高,根据网上资料来看,RabbitMQ也是首选;
4.RabbitMQ的工作机制
(1)生产者、消费者和代理
在了解消息通讯之前首先要了解3个概念:生产者、消费者和代理。
生产者:消息的创建者,负责创建和推送数据到消息服务器;
消费者:消息的接收方,用于处理数据和确认消息;
代理:就是RabbitMQ本身,用于扮演“快递”的角色,本身不生产消息,只是扮演“快递”的角色。
(2)消息发送原理
首先你必须连接到Rabbit才能发布和消费消息,那怎么连接和发送消息的呢?
你的应用程序和Rabbit Server之间会创建一个TCP连接,一旦TCP打开,并通过了认证,认证就是你试图连接Rabbit之前发送的Rabbit服务器连接信息和用户名和密码,有点像程序连接数据库,使用Java有两种连接认证的方式,后面代码会详细介绍,一旦认证通过你的应用程序和Rabbit就创建了一条AMQP信道(Channel)。
信道是创建在“真实”TCP上的虚拟连接,AMQP命令都是通过信道发送出去的,每个信道都会有一个唯一的ID,不论是发布消息,订阅队列或者介绍消息都是通过信道完成的。
5.RabbitMQ常用的一些术语
ConnectionFactory(连接管理器):应用程序与Rabbit之间建立连接的管理器,程序代码中使用;
Channel(信道):消息推送使用的通道;
Exchange(交换器):用于接受、分配消息;
Queue(队列):用于存储生产者的消息;
RoutingKey(路由键):用于把生成者的数据分配到交换器上;
BindingKey(绑定键):用于把交换器的消息绑定到队列上;
6.RabbitMQ的七种队列模式及其应用场景
(1)简单模式(Hello World)
做最简单的事情,一个生产者对应一个消费者,RabbitMQ相当于一个消息代理,负责将A的消息转发给B
应用场景: 将发送的电子邮件放到消息队列,然后邮件服务在队列中获取邮件并发送给收件人
(2)工作队列模式(Work queues)
在多个消费者之间分配任务(竞争的消费者模式),一个生产者对应多个消费者,一般适用于执行资源密集型任务,单个消费者处理不过来,需要多个消费者进行处理
应用场景: 一个订单的处理需要10s,有多个订单可以同时放到消息队列,然后让多个消费者同时处理,这样就是并行了,而不是单个消费者的串行情况
(3)订阅模式(Publish/Subscribe)
一次向许多消费者发送消息,一个生产者发送的消息会被多个消费者获取,也就是将消息将广播到所有的消费者中。
应用场景: 更新商品库存后需要通知多个缓存和多个数据库,这里的结构应该是:
- 一个fanout类型交换机扇出两个个消息队列,分别为缓存消息队列、数据库消息队列
- 一个缓存消息队列对应着多个缓存消费者
- 一个数据库消息队列对应着多个数据库消费者
(4)路由模式(Routing)
有选择地(Routing key)接收消息,发送消息到交换机并且要指定路由key ,消费者将队列绑定到交换机时需要指定路由key,仅消费指定路由key的消息
应用场景: 如在商品库存中增加了1台iphone12,iphone12促销活动消费者指定routing key为iphone12,只有此促销活动会接收到消息,其它促销活动不关心也不会消费此routing key的消息
(5)主题模式(Topics)
根据主题(Topics)来接收消息,将路由key和某模式进行匹配,此时队列需要绑定在一个模式上,#
匹配一个词或多个词,*
只匹配一个词。
应用场景: 同上,iphone促销活动可以接收主题为iphone的消息,如iphone12、iphone13等
(6)远程过程调用(RPC)
如果我们需要在远程计算机上运行功能并等待结果就可以使用RPC,具体流程可以看图。应用场景:需要等待接口返回数据,如订单支付
(7)发布者确认(Publisher Confirms)
与发布者进行可靠的发布确认,发布者确认是RabbitMQ扩展,可以实现可靠的发布。在通道上启用发布者确认后,RabbitMQ将异步确认发送者发布的消息,这意味着它们已在服务器端处理。
应用场景: 对于消息可靠性要求较高,比如钱包扣款
7. RabbitMQ的四种交换机
(1)Fanout:广播,将消息交给所有绑定到交换机的队列,订阅模式使用此类型
(2) Direct:定向,将消息交给符合指定routing key的队列 路由模式使用此类型
(3) Topic:通配符,把消息交给符合routing pattern的队列 通配符模式使用此类型
(4) Headers:忽略routing_key,使用Headers信息(一个Hash的数据结构)进行匹配,优势在于可以有更多更灵活的匹配规则
8.延时队列的定义及其应用场景
(1) 延时队列的定义
延时队列就是用来存放需要在指定时间被处理的元素的队列。
(2) 延时队列的应用场景
a.订单在十分钟之内未支付则自动取消。
b.新创建的店铺,如果在十天内都没有上传过商品,则自动发送消息提醒。
c.账单在一周内未支付,则自动结算。
d.用户注册成功后,如果三天内没有登陆则进行短信提醒。
e.用户发起退款,如果三天内没有得到处理则通知相关运营人员。
f.预定会议后,需要在预定的时间点前十分钟通知各个与会人员参加会议。
9.死信队列的一些相关术语
(1)死信的定义
死信,在官网中对应的单词为“Dead Letter”
“死信”是RabbitMQ中的一种消息机制,当你在消费消息时,如果队列里的消息出现以下情况:
- 消息被否定确认,使用channel.BasicNack或 channel.BasicReject,并且此时
requeue
属性被设置为false
。 - 消息在队列的存活时间超过设置的TTL时间。
- 消息队列的消息数量已经超过最大队列长度。
那么该消息将成为“死信”。
“死信”消息会被RabbitMQ进行特殊处理,如果配置了死信队列信息,那么该消息将会被丢进死信队列中,如果没有配置,则该消息将会被丢弃。
(2)TTL的定义
TTL是RabbitMQ中一个消息或者队列的属性,表明一条消息或者该队列中的所有消息的最大存活时间,单位是毫秒。换句话说,如果一条消息设置了TTL属性或者进入了设置TTL属性的队列,那么这条消息如果在TTL设置的时间内没有被消费,则会成为“死信”。
(3)死信队列的生命周期
a.业务消息被投入业务队列
b.消费者消费业务队列的消息,由于处理过程中发生异常,于是进行了nack或者reject操作
c.被nack或者reject的消息由RabbitMQ投递到死信交换机中
d.死信交换机将消息投入到对应的死信队列
e.死信队列的消费者消费死信消息
(4)死信队列的总结
死信队列并不是什么特殊的队列,只不过是绑定在死信交换机上的队列。死信交换机也不是什么特殊的交换机,只不过是用来接受死信的交换机,所以可以为任何类型【Direct、Fanout、Topic】。一般来说,会为每个业务队列分配一个独有的路由key,并对应的配置一个死信队列进行监听,也就是说,一般会为每个重要的业务队列配置一个死信队列。
参考:https://www.cnblogs.com/vipstone/p/9275256.html
https://mp.weixin.qq.com/s/QG3uXhhpkE_Uo6Me15mxdg
https://www.cnblogs.com/mfrank/p/11184929.html