今天这篇文章是比较偏“教程”一点的文章。但也由浅入深,认真地分析了源码,并且介绍了一些在使用Spring Cache中常见的问题和解决方案,肯定是比简单的入门文档更有深度一些的,相信大家看了之后会有一定的收获。
RabbitMQ是一个开源的消息代理和队列服务器,用来通过普通协议在完全不同的应用之间共享数据,它是使用Erlang
语言来编写的,并且是基于AMQP
协议的;
RabbitMQ高性能的原因
Erlang
语言最初在于交换机领域的架构模式,这样使得RabbitMQ在Broker之间进行数据交互的性能是非常优秀的)Socket
一样的延迟什么是AMQP高级消息队列协议
AMQP(Advanced Message Queueing Protocol)定义:具有现代特征的二进制协议。是一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计
AMQP协议模型:
Publisher 推送消息前先与Server建立连接,找到Virtual host
,然后将消息推送至Exchange交换机。而交换机与Message Queue
有绑定关系(一个交换机相当于一个独立的虚拟机,而这个虚拟机内的各种独立的应用就相当于一个Queue,这个Queue与交换机绑定),Consumer
通过绑定的对队列,而交换机也绑定了队列。发送者将消息发送给交换机,这样就能完成消息的推送了
整体架构图
Broker
消息队列服务进程,接收客户端的连接,实现AMQP实体服务。
Connection
连接,应用程序与Broker
的网络连接。
Producer
消息生产者,即生产方客户端,生产方客户端将消息发送到MQ。
Consumer
消息消费者,即消费方客户端,接收MQ转发的消息。
Channel
网络信道,几乎所有的操作都在Channel
中进行,Channel是进行消息读写的通道。客户端可建立多个Channel,每个Channel代表一个会话任务
Message
消息,服务器和应用程序之间传送的数据,由Properties
和Body组成。Properties可以对消息进行修饰,比如消息的优先级、延迟等高级特性;Body则就是消息体内容。
Virtual Host
虚拟地址,用于进行逻辑隔离,最上层的消息路由。一个Virtual Host里面可以有若干个Exchange和Queue,同一个Virtual Host
里面不能有相同名称的Exchange或Queue
Exchange
交换机,接收消息,根据路由键转发消息到绑定的队列。
常见的有4种不同的交换机类型:
扇形交换机
扇形交换机是最基本的交换机类型,扇形交换机会把能接收到的消息全部发送给绑定在自己身上的队列。因为广播不需要思考,所以扇形交换机处理消息的速度也是所有的交换机类型里面最快的
直连交换机
直连交换机是一种带路由功能的交换机,一个队列会和一个交换机绑定,除此之外再绑定一个routing_key
,当消息被发送的时候,需要指定一个binding_key
,这个消息被送达交换机的时候,就会被这个交换机送到指定的队列里面去。同样的一个binding_key
也是支持应用到多个队列中的
适用场景:有优先级的任务,根据任务的优先级把消息发送到对应的队列,这样可以指派更多的资源去处理高优先级的队列
主题交换机
直连交换机的routing_key
方案非常简单,如果我们希望一条消息发送给多个队列,那么这个交换机需要绑定上非常多的routing_key
,假设每个交换机上都绑定一堆的routing_key
连接到各个队列上。那么消息的管理就会异常地困难。
所以RabbitMQ
提供了一种主题交换机,发送到主题交换机上的消息需要携带指定规则的routing_key
,主题交换机会根据这个规则将数据发送到对应的(多个)队列上。
主题交换机的routing_key
需要有一定的规则,交换机和队列的binding_key
需要采用*.#.*.....
的格式,每个部分用.
分开,其中:
*
表示一个单词#
表示任意数量(零个或多个)单词当一个队列的绑定键为#
的时候,这个队列将会无视消息的路由键,接收所有的消息
首部交换机
首部交换机是忽略routing_key
的一种路由方式。路由器和交换机路由的规则是通过Headers
信息来交换的,这个有点像HTTP
的Headers
。
将一个交换机声明成首部交换机,绑定一个队列的时候,定义一个Hash
的数据结构,消息发送的时候,会携带一组hash数据结构的信息,当Hash
的内容匹配上的时候,消息就会被写入队列。
绑定交换机和队列的时候,Hash结构中要求携带一个键x-match
,这个键的Value可以是any或者all,这代表消息携带的Hash是需要全部匹配(all),还是仅匹配一个键(any)就可以了
相比直连交换机,首部交换机的优势是匹配的规则不被限定为字符串
arguments
的其中一个就能匹配上,注意这里是键值对的完全匹配,只匹配到键了,值却不一样是不行的;Entry
必须和绑定在队列上的所有Entry完全匹配Binding
Exchange和Queue之间的虚拟连接,Exchange在与多个Message Queue发生Binding后会生成一张路由表,路由表中存储着Message Queue
所需消息的限制条件即Binding Key。当Exchange收到Message时会解析其Header得到Routing Key,Exchange根据Routing Key与Exchange Type将Message路由到Message Queue。Binding Key由Consumer在Binding Exchange
与Message Queue时指定,而Routing Key由Producer发送Message时指定,两者的匹配方式由Exchange Type决定
Routing Key
一个路由规则,虚拟机可用它来确定如何路由一个特定消息。
Queue
也称为Message Queue
,消息队列,保存消息并将它们转发给消费者。
消息发布流程:
Broker
建立通道。消息接收流程:
Broker
建立通道。消息流转过程
生产者生产出Message并投递到Exchange
上
一个Exchange可以绑定多个Message Queue
,它根据路由策略(routing key
)路由到指定的队列,最后由消费端去监听队列
队列模式:
对于任务过重或任务较多情况使用工作队列可以提高任务处理的速度。
1、一条消息只会被一个消费者接收;
2、rabbitmq采用轮询的方式将消息是平均发送给消费者的;
3、消费者在处理完某条消息后,才会收到下一条消息。
发布订阅模式:
1、每个消费者监听自己的队列。
2、生产者将消息发给broker
,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队列都将接收到消息
对应交换机中的fanout
类型
路由模式:
1、每个消费者监听自己的队列,并且设置routingkey。
2、生产者将消息发给交换机,由交换机根据routingkey
来转发消息到指定的队列。
对应交换机中的direct
类型
通配符模式:
对应交换机中的topics
类型
Header转发器模式:
对应交换机中的header
类型
远程过程调用模式:
RPC即客户端远程调用服务端的方法,使用MQ可以实现RPC的异步调用,基于Direct交换机实现,流程如下:
RPC
请求队列发送RPC调用消息,同时监听RPC响应队列。RPC
响应队列。小编也是很有感触,如果一直都是在中小公司,没有接触过大型的互联网架构设计的话,只靠自己看书去提升可能一辈子都很难达到高级架构师的技术和认知高度。向厉害的人去学习是最有效减少时间摸索、精力浪费的方式。
我们选择的这个行业就一直要持续的学习,又很吃青春饭。
虽然大家可能经常见到说程序员年薪几十万,但这样的人毕竟不是大部份,要么是有名校光环,要么是在阿里华为这样的大企业。年龄一大,更有可能被裁。
小编整理的学习资料分享一波!
送给每一位想学习Java小伙伴,用来提升自己。想要资料的可以点击这里免费获取
见到说程序员年薪几十万,但这样的人毕竟不是大部份,要么是有名校光环,要么是在阿里华为这样的大企业。年龄一大,更有可能被裁。
小编整理的学习资料分享一波!
送给每一位想学习Java小伙伴,用来提升自己。想要资料的可以点击这里免费获取
[外链图片转存中…(img-KimFEaZr-1621844426063)]
本文到这里就结束了,喜欢的朋友可以帮忙点赞和评论一下,感谢支持!