小蔡学Java

RabbitMQ入门

2023-06-23 20:14 1042 0 消息中间件 RabbitMQ消息中间件

前言开头

RabbitMQ是一款使用Erlang语言开发的,实现 AMQP(Advanced Message Queuing Protocol )的开源消息中间件。它支持多种客户端如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX,持久化,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。 所以笔者整理了这篇RabbitMQ入门的文章根据下方思维导图来一一介绍。

什么是消息中间件

消息队列中间件是分布式系统中重要的组件,它提供了一种异步、可靠、可伸缩的消息传递机制;主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。

为什么使用消息中间件

先说一下它常见使用场景,比较核心的有 3 个:解耦、异步、削峰。

解耦

如下图所示,快递放入快递柜后,需要经历扣费、通知用户、通知快递公司三个业务动作;如果按照传统做法依次执行这些流程,那么当其中某个步骤异常,就会导致后续操作无法进行下去。 而当消息写入MQ,由后续三个子系统各自消费,那么其中某个子系统异常也不会导致其他子系统无法进行操作。

异步

如下图所示,快递投柜后直接结束了,无需等待到通知用户或通知快递公司再结束。系统会直接将消息投递到MQ,然后就直接返回响应给用户,具体的扣费以及后续的通知,都是异步操作的,无需用户关心,可以大大地提高性能。原先响应时间需要各子系统的总和,共800ms,现如今发送到MQ后交给系统异步处理用户只需要100ms就可以完成操作。

削峰

如下图所示。假设用户投递快递,高峰达到20w/s,但是我们的业务系统每秒只能处理10w个请求,对于如此庞大的请求处理不过来,导致系统瘫痪。如果使用MQ,我们可以把数据发送到MQ堆积着,然后由后台每次拉取10w个请求进行处理。

RabbitMQ的特点

  • 可靠性:支持持久化、传输确认及发布确认来保证可靠性。
  • 灵活的路由:在消息进入队列之前,通过交换机进行路由消息。分发消息策略有:简单模式、工作队列模式、发布订阅模式、路由模式、通配符模式。
  • 扩展性:多个RabbitMQ服务器可以组成一个集群,形成一个逻辑Broker。
  • 高可用性:队列可以在集群中的机器设置镜像,使得在部分节点出现故障时,队列仍然可用。
  • 多种协议:RabbitmMQ除了AMQP协议外,还支持STOMP、MQTT等多种消息队列协议。
  • 可视化管理界面:RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息、集群中的节点等。
  • 插件机制:RabbitMQ 提供了许多插件 ,可以通过插件进行扩展,也可以编写自己的插件。

RabbitMQ核心概念

RabbitMQ整体上是一个生产者与消费者模型,主要负责接收、存储和转发消息。它消息传递的过程如同,你寄快递,快递站可以暂存并且最终将快递由快递员送到收件人手上,RabbitMQ 就好比由包裹、快递站和快递员组成的一个系统,更像是一种交换机模型,其架构示例图如下:

Produer(生产者)和Consumer(消费者)

  • Producer(生产者):消息生产者,用于发布消息。
  • Consumer(消费者):消息消费者,消费队列中存储的消息。 消息一般由消息头和消息体组成。消息头(Label)用于存储与消息相关的元数据:如路由键 (RountingKey)和其他可选配置 (properties) 信息。消息体(payLoad )为实际需要传递的数据,消息体是不透明的。生产者将消息发送给RabbitMQ后,其会根据消息头把消息发送给感兴趣的Consumer。

Exchange(交换机)

消息队列交换器,根据一定的路由规则将消息路由到一个或多个队列。如果路由不到,当mandatory为true时则返回给生产者,mandatory为false时则直接丢弃。

生产者在发送消息给交换机时,会指定一个RoutingKey(路由键),用来指定路由规则,这个RoutingKey需要与交换机类型和BindingKey(绑定键)联合使用才能生效。如下图所示,RabbitMQ通过Binding(绑定)将Exchange(交换器)与Queue(消息队列)关联起来,在绑定的时候指定一个BindingKey,这样RabbitMQ就知道如何将消息正确发送到对应的队列中。绑定就是基于路由键将交换器和消息队列连接起来的路由规则,Exchange和Queue的绑定可以是多对多的关系。

生产者将消费者发送给交换机时,当RoutingKey与BindingKey相匹配,消息会被路由到对应的队列中。绑定多个队列到同一个Exchange时允许使用相同的BindingKey。BindingKey 并不是在所有的情况下都生效,它依赖于交换器类型,比如 fanout 类型的交换器就会无视,而是将消息路由到所有绑定到该交换器的队列中。

Queue(消息队列)

用来存储消息直到发送给消费者。多个消费者可以订阅同一个队列,此时队列会将收到的消息以轮询(Round-Robin)的方式分发给多个消费者进行处理,即每条消息只发送给一个消费者,这样避免消息被重复消费。RabbiMQ不支持队列层面的广播消费。

Broker(消息中间件的服务节点)

简单来说Broker就是消息队列服务器实体,也可以看作是RabbitMQ服务节点或RabbitMQ服务实例。

Exchange Types(交换器类型)

Direct Exchange

直链交换机说白了就是它会将消息路由到Bindingkey与RoutingKey完全匹配的Queue 中。

以上图为例,如果Producer发送消息时RotuingKey=insert时,那么这时候消息会被Exchange路由到Queue1和Queue2这两个队列。如果我们以RotuingKey=delete和RotuingKey=update发送消息时,这时消息只会被推送到 Queue2队列中。其他RoutingKey的消息将会被丢弃。

Fanout exchange

fanout 类型的交换机会将消息路由到所有与它绑定的队列中,不管RoutingKey是否匹配。它通常用来广播消息。

Topic Exchange

topic类型交换机的路由规则是一种模糊匹配,可以通过通配符满足部分规则就可以传送消息。

  • RoutingKey为一个点好“.”分割的字符串(我们将被句点号 “. ” 分隔开的每一段独立的字符串称为一个单词),比如“com.rabbitmq.client"、 "org.springframework.amqp"、"org.springframework.boot"。BindingKey 和 RoutingKey 一样也是点号“.”分隔的字符串。
  • BdingKey中可以存在两种特殊字符“”与“#”,用来做模糊匹配,其中“”用于匹配一个单词,“#”用来匹配多个单词(可以是零个)。

以上图为例:

  • 当生产者发送消息RoutingKey="com.rabbitmq.client"的时候,会同时被路由到Queue1和Queue2;
  • 当RoutingKey="org.springframework.amqp"时,消息只会被路由到Queue2;
  • 当RoutingKey="org.springframework.boot"时,消息只会被路由到Queue2;
  • 当RoutingKey="java.lang.String"时,消息会被丢弃或者返回给生产者;

Headers Exchange

这种交换机不是很常用,可以认为它是直连交换机的另一个表现形式,只不过它更灵活,它的路由不是通过RoutingKey进行路由匹配,而是根据匹配请求头中所带的键值对进行路由。

  • 绑定一个队列到 Headers Exchange上,会同时绑定多个用于匹配的header。
  • 传来的消息会携带header,以及会有一个 “x-match” 参数。当 “x-match” 设置为 “any” 时,消息头的任意一个值被匹配就可以满足条件,而当 “x-match” 设置为 “all” 的时候,就需要消息头的所有值都匹配成功。

评论( 0 )

  • 博主 Mr Cai
  • 坐标 河南 信阳
  • 标签 Java、SpringBoot、消息中间件、Web、Code爱好者

文章目录