开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情
Rabbit中文是兔子,刚好今年也是兔年,完美契合!
作为一名Java工程师,我们日常开发过程中可能因业务需求会用到消息队列。但是自己从来都只是简单的浏览网上的一些写法,本着能用就行的原则,只要把消息成功发送到 RabbitMQ 服务器,再成功被其他服务消费就觉得OK了。自己从来没想过去深入的了解一下RabbitMQ,刚好最近项目上没有什么工作量,才得以抽出时间来看看这方面的书籍。东西有点多,无法在一篇文章中全部体现。上篇打算向大家介绍一些概念性的东西,后面再结合实际的代码来实践,希望各位能耐心看完全部!
小插曲
在进入正题之前,我想先跟大家说一下AMQP这个高级消息队列协议,为什么要了解这个呢?因为笔者之前作为初级程序员面试时简历上填写了熟悉RabbitMQ,结果被面试官第一个问题就被问趴了,他问我:“你知道RabbitMQ是基于什么协议开发的吗?”,我当场就懵了,结果大家可想而知被刷了,不过知耻而后勇嘛!话不多说,AMQP的解释如下:
AMQP(Advanced Message Queuing Protocol,高级消息队列协议)是应用层协议的开放标准,是为面向消息的中间件设计。基于此协议的客户端可与消息中间件传递消息,从而不受产品、开发语言等条件限制
RabbitMQ正是基于这个开源AMQP协议实现的一款消息中间件,服务器端语言用Erlang语言编写,支持多种客户端,例如:Java、C、Python、Ruby等。RabbitMQ作为主流的消息中间件,其解决了多服务之间的耦合性问题,让原本同步等待的操作可以变成异步以节省时间。同时也起到了消息缓冲、消息分发的作用。在易用性、扩展性、高可用性等方面表现不俗。
RabbitMQ 的优势
RabbitMQ的主要优势如下:
- 可靠性(Reliability):使用了一些机制来保证可靠性,比如持久化、传输确认、发布确认。
- 灵活的路由(Flexible Routing):在消息进入队列之前,通过Exchange来路由消息。对于典型的路由功能,Rabbit已经提供了一些内置的Exchange来实现。针对更复杂的路由功能,既可以将多个Exchange绑定在一起,又可以通过插件机制实现自己的Exchange。
- 消息集群(Clustering):多个RabbitMQ服务器可以组成一个集群,形成一个逻辑Broker。
- 高可用(Highly Available Queues):队列可以在集群中的机器上进行镜像,使得在部分节点出现问题的情况下队列仍然可用。
- 多种协议(Multi-Protocol):支持多种消息队列协议,如STOMP、MQTT等。
- 多种语言客户端(Many Clients):几乎支持所有常用语言,比如Java、.NET、Ruby等。
- 管理界面(Management UI):提供了易用的用户界面,使得用户可以监控和管理消息Broker的许多方面。
- 跟踪机制(Tracing):如果消息异常,RabbitMQ提供了消息的跟踪机制,使用者可以找出发生了什么。
- 插件机制(Plugin System):提供了许多插件进行扩展,也可以编辑自己的插件。
RabbitMQ 核心点
RabbitMQ中有几个非常重要的点必须得搞清楚,这样后面在使用时就能快速上手。
- Broker(服务实体):标识消息队列服务器实体。
- Virtual Host(虚拟主机):在RabbitMQ中,用户只能在虚拟主机的粒度上进行权限控制。
- Exchange(交换机):就像现实中网络硬件交换机一样,不生产数据只是数据的搬运工。在RabbitMQ中客户端不会直接发消息给服务端,而是通过交换机转发的。交换机不进行消息存储,只负责转发。
- Queue(队列):用来保存消息的容器,直到被消费者消费。ps一个消息可以投入多个队列。
- Binding(绑定):负责将交换机和队列进行相互绑定
Exchange 交换机
Exchange在RabbitMQ起着至关重要的作用,消息的分发离不开它。Exchange中有2个关键词,RoutingKey和BindingKey
- BindingKey是交换机和消息队列绑定的规则描述。
- RoutingKey是消息发送时携带的消息路由信息描述。
当消息发送到交换机(Exchange)时,通过消息携带的RoutingKey与当前交换机所有绑定的BindingKey进行匹配,如果满足匹配规则,则往BindingKey所绑定的消息队列发送消息,这样就解决了向RabbitMQ发送一次消息,可以分发到不同的消息队列,实现消息路由分发的功能。
Exchange支持4种消息分发类型:
| 模式 | 描述 |
|---|---|
| Direct | 其行为是“先匹配,再发送”,即在绑定时设置一个BindingKey,当消息的RoutingKey匹配队列绑定的BindingKey时,才会被交换机发送到绑定的队列中。 |
| Topic | 这是小编认为最灵活的按规则转发消息模式。支持用 * 或 # 的通配符形式进行绑定。* 表示匹配一个单词,# 表示匹配0个或者多个单词。例如,某消息队列绑定的BindingKey为 *.test.# 时,能够匹配到RoutingKey为 dev.test 和 prod.test.db 的消息,但是不匹配 test.hello |
| Headers | 通过设置header attribute参数类型的交换机。根据应用程序消息的特定属性进行匹配,这些消息可能在绑定key中标记为可选或者必选 |
| Fanout | 将消息以广播的形式转发到所有绑定队列,而不考虑队列绑定的BindingKey的值。 |
看到这里的小伙伴辛苦啦!以上内容虽然繁琐,但只要稍微花点时间了解一下就会发现后面深入学习时就不会太吃力!下一篇文章小编将以代码的形式给大伙逐一演示这几种转发模式的区别。