一.产生背景
RabbitMQ,开源消息代理之一,采用AMQP(Advanced Message Queuing Protocol)协议实现,消息中间件充当了不同应用程序之间的介质,解耦了不同平台之间的通信;
二.作用
2.1 解耦
消息中间件在处理中插入一个隐含接口层,生产者,消费者可以独立扩展实现该接口,而不需要将他们强行绑定在一起;
2.2 冗余(存储)
会将消息持久化存储下来,避免消息丢失;
2.3 扩展性
解耦了应用的处理过程,只需增加处理过程就可以提高消息的入队和处理的效率;
2.4 削峰
在访问量剧增的时候,支撑突发访问压力
2.5可恢复性
部分组件失效时,不影响整个系统,降低进程间的耦合度,即使一个消费者进程挂掉,待系统恢复后可继续进行处理消息;
2.6 顺序保证
保证消息的处理顺序;
2.7 缓冲
在数据量大时降低系统的压力,发送到中间件的消息可依赖系统处理能力,逐步消费消息;
2.8异步通信
应用中的的一些场景,比如下单后给用户发送短息,我们并不需要立即处理,就可以采用异步化方式,提高系统接口的响应速度;
三.名词解释
基本概念
3.1 ConnectionFactory、Connection、Channel
封装对外提供使用的API 对象,每个Connection
为建立的Tcp 物理连接,执行授权,认证,IP 地址解析,路由等网络服务
ConnectionFactory 为产生Connection 的工厂
Channel是物理TCP连接中的虚拟连接。当应用通过Connection与消息队列RabbitMQ建立连接后,所有的AMQP协议操作(例如创建队列、发送消息、接收消息等)都会通过Connection中的Channel完成。Channel可以复用Connection,即一个Connection下可以建立多个Channel。
3.2 Producer
发送消息的生产者;
3.3 Consumer
处理消息的消费者,同一队列有多个消费者订阅,则默认按照轮询的方式均等分配消息;
3.3 Queue
存储消息的容器;
image.png
3.4 Exchange(管理消息发送的角色)
交换器 ,消息临时经过的场所,生产者将消息发送到Exchange,由Exchange 进行消息路由;
image.png
3.5 Broker
消息中间件服务节点;
3.6 RoutingKey
路由键,指定消息的路由规则,在生产者将消息发送到Exchange时进行指定;
3.6 BindingKey
Rabbitmq 通过Exchange与Queue 建立联系,这样才能知道发送到交换机消息依赖什么样的规则进行投递到队列中, 当消息所携带的RoutingKey 与BindingKey 匹配时,决定了消息最终到达那一个队列,当然,还得依赖于交换器的类型,当交换器类型为fanout类型时,会忽略BindingKey,将消息路由到所有的队列中;
交换器类型
RabbitMQ常用的Exchange Type有fanout、direct、topic、headers这四种;
fanout
fanout类型的Exchange路由规则非常简单,它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中;
direct
direct 类型的会把消息路由到那些binding key与routing key完全匹配的Queue中;
image.png
如果发送一条消息,消息的routingKey 为info,那么消息会被路由到Queue 2中;
如果发送一条消息,消息的routingKey 未warning ,那么消息会被路由到Queue 1和Queue 2中;
topic
topic类型的Exchange在匹配规则上进行了扩展,它与direct类型的Exchage相似,也是将消息路由到binding key与routing key相匹配的Queue中,但这里的匹配规则有些不同,规定:
routing key 为一个点号"."分隔的字符串(被点号分隔开的每一个单词称为一个字符);
binging key 同样使用一个点号"." 分隔字符串;
binging key 存在两种特殊字符串,“#” 和"" 用于做模糊匹配, "#" 用于任意个单词(零个,1个,多个),"" 用于匹配最多一个单词,可以是零个;
当发送消息的路由键是“com.rabbitmq.test” ,消息将会匹配Queue1和Queue2;
当发送消息路由键是"com.123",消息将会匹配Queue2;
当发送消息路由键是"rabbitmq.test",消息将会匹配Queue1;
当发送消息路由键是“test123”,消息将会丢弃或返回给生产者,没有与之匹配的绑定键;
headers
headers 类型的交换器不依赖于路由键的匹配规则来路由消息,而是根据发送的消息内容中的headers 属性进行匹配,在绑定队列和交换器指定一组键值对,当发送消息到交换器时,rabbitmq 会获取该消息的headers (键值对形式),对比其中的键值对是否完全匹配队列和交换器绑定时指定的键值对,如果完全匹配则路由到该队列,否则不会进行路由;
消息的运作流程
生产者生产消息流程
生产者连接broker ,建立Connection,开启信道Channel;
生产者声明交换器,设置属性(类型,持久化等);
生产者声明队列,设置属性(是否排他,持久化等);
生产者通过绑定键将交换机和队列进行绑定;
生产者发送消息到broker ,包含路由键,交换器信息;
对应的交换器根据接收到的路由键与绑定键进行匹配查找对应的队列,找到,则将消息存储到相应的队列,如果没有找到,根据生产者属性配置或是否设置备份交换器决定消息是丢弃,存储备份交换器还是回退给生产者;
关闭信道,关闭连接;
消费者消费消息流程
消费者连接到broker ,建立Connection,开启信道;
消息者向broker 请求消费队列的消息,设置相应的回调函数;
等待broker 回应并投递消息,消费者接受消息;
消费者消费完消息后,手动发送ack确认;
rabbitmq 从队列删除已经被确认的消息;
关闭信道;
网友评论