[转帖]RabbitMQ基础概念详细介绍

rabbitmq,基础,概念,详细,介绍 · 浏览次数 : 0

小编点评

**RabbitMQ简介** RabbitMQ 是一个高级消息队列协议,它是面向消息的中间件,用于组件之间的通信。 **主要特征:** - 面向消息 - 队列、路由(包括点对点和发布/订阅) - 可靠性 - 安全 **主要组件:** - **ConnectionFactory:**创建连接工厂。 - **Connection:**连接到 RabbitMQ 的 socket 连接。 - **Channel(信道):**建立在 TCP 连接上的虚拟连接。 - **Channel:**与 Channel 相关的通道,用于定义队列、交换器等。 - **Binding:**用于绑定 Channel 到交换器或队列。 **配置示例:** ```java // 建立连接工厂 ConnectionFactory connectionFactory = new ConnectionFactory(); // 建立连接 Connection connection = connectionFactory.createConnection(); // 建立通道 Channel channel = connection.createChannel(); // 建立绑定 channel.bind(bindingKey, routingKey); // 关闭连接 connection.close(); ``` **使用示例:** ```java // 发送消息 channel.basicPublish("hello", "world"); // 接收消息 Message message = channel.basicReceive(); String content = message.getBody(String.class); ``` **其他功能:** - RPC(远程过程调用)支持 - 可扩展性 - 高性能 **结论:** RabbitMQ 是一个功能强大的消息队列,它提供了许多功能,可以用于各种应用程序的需要。

正文

https://www.jianshu.com/p/e55e971aebd8

 

AMQP简介

AMQP,即 Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦和通讯。

AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。

RabbitMQ是一个开源的AMQP实现,服务器端用 Erlang 语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息,具有很高的易用性和可用性。

安装部署

安装部署请参考Docker 安装部署RabbitMQ

AMQP协议中的几个重要概念

ConnectionFactory、Connection、Channel

ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。

  • ConnectionFactory:ConnectionFactory为Connection的制造工厂。
  • Connection:Connection是RabbitMQ的socket链接,它封装了socket协议相关部分逻辑。
  • Channel(信道):信道是建立在“真实的”TCP连接上的虚拟连接,在一条TCP链接上创建多少条信道是没有限制的,把他想象成光纤就是可以了。它是我们与RabbitMQ打交道的最重要的一个接口,我们大部分的业务操作是在Channel这个接口中完成的,包括定义Queue、定义Exchange、绑定Queue与Exchange、发布消息等。

Queue(队列)

Queue 是 RabbitMQ 的内部对象,用于存储消息。


 
image.png

RabbitMQ中的消息只能存储在 Queue 中。生产者(下图中的P)生产消息并最终投递到Queue中,消费者(下图中的C)可以从Queue中获取消息并消费,消费者可以是一个或者多个。


 
队列

Message acknowledgment(ack 消息的确认):

在实际应用中,可能会发生消费者收到Queue中的消息,但没有处理完成就宕机(或出现其他意外)的情况,这种情况下就可能会导致消息丢失。为了避免这种情况发生,我们可以要求消费者在消费完消息后发送一个回执给RabbitMQ,RabbitMQ收到消息回执(ack)后才将该消息从Queue中移除;如果RabbitMQ没有收到回执并检测到消费者的RabbitMQ连接断开,则RabbitMQ会将该消息发送给其他消费者(如果存在多个消费者)进行处理。这里不存在timeout概念,一个消费者处理消息时间再长也不会导致该消息被发送给其他消费者,除非它的RabbitMQ连接断开。

这里会产生另外一个问题,如果我们的开发人员在处理完业务逻辑后,忘记发送回执给RabbitMQ,这将会导致严重的bug——Queue中堆积的消息会越来越多;消费者重启后会重复消费这些消息并重复执行业务逻辑…

另外pub message是没有ack的。

Message durability(消息的持久化)

如果我们希望即使在RabbitMQ服务重启的情况下,也不会丢失消息,我们可以将Queue与Message都设置为可持久化的(durable),这样可以保证绝大部分情况下我们的RabbitMQ消息不会丢失。但依然解决不了小概率丢失事件的发生(比如RabbitMQ服务器已经接收到生产者的消息,但还没来得及持久化该消息时RabbitMQ服务器就断电了),如果我们需要对这种小概率事件也要管理起来,那么我们要用到事务。由于这里仅为RabbitMQ的简单介绍,所以这里将不讲解RabbitMQ相关的事务。具体可以参考 RabbitMQ之消息确认机制(事务+Confirm)

Prefetch count(每次向消费者发送消息的总数)

前面我们讲到如果有多个消费者同时订阅同一个Queue中的消息,Queue中的消息会被平摊给多个消费者。这时如果每个消息的处理时间不同,就有可能会导致某些消费者一直在忙,而另外一些消费者很快就处理完手头工作并一直空闲的情况。我们可以通过设置prefetchCount来限制Queue每次发送给每个消费者的消息数,比如我们设置prefetchCount=1,则Queue每次给每个消费者发送一条消息;消费者处理完这条消息后Queue会再给该消费者发送一条消息。

 
image.png

Exchange(交换器)

Exchange生产者将消息发送到 Exchange(交换器,下图中的X),由 Exchange 根据一定的规则将消息路由到一个或多个 Queue 中(或者丢弃)。

 
image.png

Routing key(路由key)

生产者在将消息发送给 Exchange 的时候,一般会指定一个 routing key,来指定这个消息的路由规则。 Exchange 会根据 routing key 和 Exchange Type(交换器类型) 以及 Binding key 的匹配情况来决定把消息路由到哪个 Queue。RabbitMQ为routing key设定的长度限制为255 bytes。

Binding(绑定)

RabbitMQ中通过 Binding 将 Exchange 与 Queue 关联起来。


 
image.png

Binding key

在绑定(Binding) Exchange 与 Queue 关系的同时,一般会指定一个 binding key。

Exchange Types (交换器类型)

RabbitMQ常用的Exchange Type有 Fanout、 Direct、 Topic、 Headers 这四种。

  • Fanout
    这种类型的Exchange路由规则非常简单,它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中,这时 Routing key 不起作用。


     
    image.png
  • Direct
    这种类型的Exchange路由规则也很简单,它会把消息路由到那些 binding key 与 routing key完全匹配的Queue中。


     
    image.png

在这个设置中,我们可以看到两个队列Q1、Q2直接绑定到了交换器X上。 第一个队列用绑定key橙色(orange)绑定,第二个队列有两个绑定,一个绑定key为黑色(black),另一个为绿色(green)。

在这种设置中,通过路由键橙色发布到交换器的消息将被路由到队列Q1。 带有黑色或绿色的路由键的消息将进入Q2。 所有其他消息将被丢弃。

 
image.png

在上面列子中,routingKey=”error”的消息发送Exchange后,Exchange会将消息路由到Queue1(amqp.gen-S9b…,这是由RabbitMQ自动生成的Queue名称)和Queue2(amqp.gen-Agl…);如果routingKey=”info”或routingKey=”warning”的消息发到Exchange,Exchange只会将消息路由到Queue2。 所有其他消息将被丢弃。

  • Topic
    这种类型的Exchange的路由规则支持 binding key 和 routing key 的模糊匹配,会把消息路由到满足条件的Queue。 binding key 中可以存在两种特殊字符 *与 #,用于做模糊匹配,其中 * 用于匹配一个单词,# 用于匹配0个或多个单词,单词以符号“.”为分隔符。
 
image.png

以上图中的配置为例,routingKey=”quick.orange.rabbit”的消息会同时路由到Q1与Q2,routingKey=”lazy.orange.fox”的消息会路由到Q1与Q2,routingKey=”lazy.brown.fox”的消息会路由到Q2,routingKey=”lazy.pink.rabbit”的消息会路由到Q2(只会投递给Q2一次,虽然这个routingKey与Q2的两个bindingKey都匹配);routingKey=”quick.brown.fox”、routingKey=”orange”、routingKey=”quick.orange.male.rabbit”的消息将会被丢弃,因为它们没有匹配任何bindingKey。

  • Headers
    这种类型的Exchange不依赖于 routing key 与 binding key 的匹配规则来路由消息,而是根据发送的消息内容中的 headers 属性进行匹配。

RPC

MQ本身是基于异步的消息处理,前面的示例中所有的生产者(P)将消息发送到RabbitMQ后不会知道消费者(C)处理成功或者失败(甚至连有没有消费者来处理这条消息都不知道)。
但实际的应用场景中,我们很可能需要一些同步处理,需要同步等待服务端将我的消息处理完成后再进行下一步处理。这相当于RPC(Remote Procedure Call,远程过程调用)。在RabbitMQ中也支持RPC。


 
image.png

RabbitMQ中实现RPC的机制是:

  1. 客户端发送请求(消息)时,在消息的属性中(MessageProperties,在AMQP协议中定义了14中properties,这些属性会随着消息一起发送)设置两个值replyTo(一个Queue名称,用于告诉服务器处理完成后将通知我的消息发送到这个Queue中)和correlationId(此次请求的标识号,服务器处理完成后需要将此属性返还,客户端将根据这个id了解哪条请求被成功执行了或执行失败)
  2. 服务器端收到消息并处理
  3. 服务器端处理完消息后,将生成一条应答消息到replyTo指定的Queue,同时带上correlationId属性
    客户端之前已订阅replyTo指定的Queue,从中收到服务器的应答消息后,根据其中的correlationId属性分析哪条请求被执行了,根据执行结果进行后续业务处理

参考:

与[转帖]RabbitMQ基础概念详细介绍相似的内容:

[转帖]RabbitMQ基础概念详细介绍

https://www.jianshu.com/p/e55e971aebd8 AMQP简介 AMQP,即 Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦和通讯。 AMQP的主要

[转帖]RabbitMQ学习笔记06:Topics

https://www.cnblogs.com/alongdidi/p/rabbitmq_tutorial_five.html 前言 在上一篇博文中我们使用direct类型的exchange改善了我们的日志系统,但是它仍然有一定的限制,它没有办法基于多个条件路由消息。 我们可能不仅仅希望基于日志级别

[转帖]RabbitMQ服务优化,修改最大连接数

https://www.cnblogs.com/hoyeong/p/16242202.html RabbitMQ的优化RabbitMQ的连接数是压垮消息队列的一个重要的指标。所以在平时使用OpenStack平台的过程中,如果大量的用户同时创建虚拟机,会导致云平台创建报错,其实就是消息队列服务的崩溃。

[转帖]RabbitMQ性能优化

https://www.cnblogs.com/zhengchunyuan/p/9253728.html 修改rabbitmq.config文件 rabbitmq.config文件时rabbitmq的配置文件,他遵守Erlang配置文件定义。 rabbitmq.config文件位置: Unix $R

[转帖]RabbitMQ的Vhost,Exchange,Queue原理分析

RabbitMQ的Vhost,Exchange,Queue原理分析https://www.cnblogs.com/zhengchunyuan/p/9253725.html Vhost分析 RabbitMQ的Vhost主要是用来划分不同业务模块。不同业务模块之间没有信息交互。 Vhost之间相互完全隔

[转帖]RabbitMQ 的重要概念(术语)

Message 消息指的是 RabbitMQ 的队列中保存的数据。 Producer 消息的生产者,即 message publisher(sender),是指负责创建和发送消息的程序。 Vhost RabbitMQ 的虚拟主机,一个 broker 里可以开设多个 vhost,用作不同用户的权限分离

[转帖]RabbitMQ 死信队列

https://blog.csdn.net/lamp_yang_3533/article/details/111463928 死信交换机 DLX(Dead-Letter-Exchange)可以称之为死信交换机,也称之为死信邮箱。 当消息在一个正常的业务队列中变成死信(dead message)之后,

[转帖]RabbitMQ 如何保证交换机中的消息不丢失

我们知道,生产者会先将消息发送给交换机,但是如果交换机此时没有匹配到相关的队列时,交换机中的消息就会出现丢失的问题。 那么,如何保证交换机中的消息不丢失呢? mandatory 参数 当 basicPublish 方法的 mandatory 参数设为 true 时,如果交换器无法匹配到绑定的队列,那

[转帖]RabbitMQ:Exchange的Fanout类型的介绍和使用

https://blog.csdn.net/weixin_45492007/article/details/106095591 1.声明 当前的内容用于本人学习和使用Fanout类型的Exchange,主要理解其主要作用 2.Fanout Exchange的官方介绍 扇出交换机将消息路由到与其绑定的

[转帖]RabbitMQ 消费者回执和发布确认

为了保证数据安全,消费者和生产者的回执(ack)都是非常重要的。 由于我们无法保证消息都能像我们期望的那样,正常到达另一端或者被 Consumer 消费成功。因此,publisher 和 consumer 都需要一种机制,来确保消息投递成功了和消息消费成功了。 在 AMQP 0-9-1 中,消费者处