开始使用 RabbitMQ 和 Python

2025年3月17日 | 阅读 8 分钟

在本教程中,我们将学习 RabbitMQ 并使用 Python 实现它。本教程还将为您提供有关消息队列的简要知识,并定义基本概念。我们将了解 RabbitMQ、消息队列、交换器等的基本功能。在深入本教程之前,让我们先对 RabbitMQ 有一个基本的了解。

什么是 RabbitMQ?

RabbitMQ 是一种流行的消息代理,用于端到端传输消息。消息是传输信息的方式。消息可以包含任何类型的信息,并且可以包含有关进程或任务的信息。消息代理就像邮局一样;当我们想要发送一些消息时,我们将信息放入信件中并将其放入邮箱,这样我们就可以确保邮递员最终会将其送达收件人。

RabbitMQ 使用一些术语,例如:

  • 生产者 - 它仅仅是生成要传输的消息。换句话说,生产者是向消费者发送消息的程序,发送消息的过程称为生产。
  • 队列 - 队列是 RabbitMQ 内部的邮局。消息流可以存储在队列中。队列只受主机内存和磁盘限制的约束。它本质上是一个大的消息缓冲区。一个队列可以从发送方获取消息,许多消费者可以尝试从一个队列接收数据。
  • 消费者 - 一个等待接收消息的程序,消费类似于接收。

注意 - 生产者、消费者和代理不必驻留在同一主机上。大多数应用程序不是,并且一个应用程序可以既是生产者又是消费者。

RabbitMQ 示例

消息代理充当各种服务(例如 - Web 应用程序)之间的桥梁。它们通过将通常会占用大量时间或资源的任务委托给没有其他工作的第三方,从而在减少 Web 应用程序服务器的负载和交付时间方面发挥着重要作用。

我们举一个真实的例子 - 一个 Web 应用程序,它获取用户上传的信息。该网站使用此信息生成 PDF 并通过电子邮件发送回用户。要创建 PDF,应用程序将需要几秒钟。因此,消息队列的作用就出现了。队列将用于执行该任务。

每次用户将信息上传到 Web 界面时,Web 应用程序将创建一个“PDF 处理”消息,其中包含用户所需的所有基本信息,并将其放入 RabbitMQ 中定义的队列。

Get Started with RabbitMQ and Python

上图是消息队列的基本图 - 有一个称为生产者的应用程序,它创建消息并将其传输到代理(消息队列)。第二个应用程序是消费者,连接到队列并订阅要处理的消息。一个软件可以作为生产者、消费者,或者既是消费者又是消息的生产者。消息存储在队列中,直到消费者检索它们。

何时以及为何使用 RabbitMQ

消息队列允许 Web 服务器快速响应,而不是被迫立即执行耗费资源的过程,从而延迟响应时间。如果我们想将消息分发给多个消费者或在工作进程之间平衡负载,消息队列将发挥重要作用。

消费者从队列中取出消息并开始处理 PDF。同时,生产者正在排队新消息。还有一个有趣的事实,消费者可以与生产者驻留在不同的服务器上,或者它们可以驻留在同一服务器上。

请求可以用一种编程语言创建,并用另一种编程语言处理。

关键是两个应用程序将仅通过它们相互发送的消息进行通信,这意味着发送方和接收方具有低耦合。

什么是交换器?

正如我们之前讨论的,消息存储在队列中;但它们并非直接存储。生产者将消息发送到交换器,交换器负责借助绑定和路由键将消息路由到不同的队列。绑定负责一个交换器。

RabbitMQ 中的消息流

让我们了解 RabbitMQ 中的消息流。

  • 生产者生产消息并将其发布到交换器。创建交换器时,必须指定类型。此主题稍后将介绍。
  • 交换器接收消息并准备路由消息。交换器会根据交换器类型考虑不同的消息属性,例如路由键。
  • 必须从交换器到队列创建绑定。在这种情况下,从交换器到队列有两种不同的队列。交换器根据消息属性将消息路由到队列中。
  • 队列保存消息,直到客户消费它们。
  • 消费者处理消息。

交换器类型

以下是主要的交换器。

  • Direct - 消息被路由到绑定键与消息路由键匹配的队列。
  • Fanout - 扇出交换器将消息传输到所有绑定到它的队列。
  • Topic - 交换器匹配绑定中指定的路由键和路由模式。
  • Headers - Headers 使用消息头属性进行路由。

RabbitMQ 安装

我们将在 Windows 上安装 RabbitMQ,这是一个简单的过程。在安装 RabbitMQ 之前,我们必须安装 Erlang 虚拟机,如果您已经安装了 Erlang,那么您可以直接安装 RabbitMQ。

1. 在 Windows 上安装 Erlang

点击官方网站并下载 OTP 22.0。然后点击上面突出显示的 OTP 22.0 Windows xx 位二进制文件;它的大小约为 94+ MB。下载 otp_win64_22.0 文件后,我们将看到以下设置窗口。

Get Started with RabbitMQ and Python

选择 Erlang 复选框,然后单击“下一步”按钮。然后选择安装 Erlang 的目标文件夹,然后单击“下一步”按钮。

Get Started with RabbitMQ and Python

它将显示开始菜单,选择并单击“安装”按钮。

Get Started with RabbitMQ and Python

现在 Erlang 安装将开始;这将需要一段时间才能完成。

Get Started with RabbitMQ and Python

现在单击关闭按钮,我们已成功安装。

2. 启用 RabbitMQ 管理插件

RabbitMQ 默认作为 Windows 服务运行;如果您对使用命令行工具更感兴趣,这取决于我们。

Get Started with RabbitMQ and Python

现在下载 RabbitMQ server.exe,如下图所示。

Get Started with RabbitMQ and Python

双击下载的 rabbitmq-server-3.8.1.exe,然后单击“下一步”。

Get Started with RabbitMQ and Python

按照上述过程,点击“完成”,安装将完成。

使用 Python 实现 RabbitMQ

现在,我们将学习如何使用 Python 实现 RabbitMQ。首先,我们创建一个 send.py 文件,它将向队列发送消息。要使用 RabbitMQ,我们需要在系统中安装 pika 模块。要安装 pika,请在终端中键入以下命令。

此命令将在本地机器上安装 pika。现在我们已准备好使用 RabbitMQ。

在上面的代码中,我们导入了 pika 模块并与本地机器上的代理建立了连接 - 因此是本地的。我们需要指定名称或 IP 地址以连接到不同的设备。

下一步是配置队列,或者我们需要确保接收队列存在。如果我们向不存在的位置发送消息,RabbitMQ 将丢弃该消息。

我们将创建 my_queue, 消息将传递到其中。

现在我们已准备好传输消息。我们将向 my_queue 发送字符串“Hello World”。

如前所述,我们无法直接将消息传递到队列。它总是需要通过一个交换器。空字符串定义默认交换器。这个交换器很特别——它允许我们精确指定消息将发送到哪个队列。我们需要在 routing_key 参数中指定队列名称。

使用以下命令关闭连接。

接收

我们将创建我们的第二个程序 receive.py,它从队列中接收消息并将其打印到屏幕上。

同样,我们需要与 RabbitMQ 服务器建立连接。我们将使用之前的代码。我们还需要检查队列是否存在,就像我们在上面的代码中检查的那样。

因此,这里可能会出现一个问题,为什么我们需要再次声明队列 - 我们已经在之前的代码中声明了它。如果我们确定队列已经存在,我们可以避免这样做。让我们举一个场景 - 如果 send.py 文件先运行。但我们还不确定哪个程序先运行。因此,最好在两个程序中都声明队列。

从队列接收消息更复杂。它通过订阅一个回调函数到队列来工作。pika 库在每个收到的消息中都会调用回调函数。在我们的程序中,该函数将在屏幕上打印消息内容。

现在我们需要通知 RabbitMQ,这个特定的回调函数应该从我们的 my_queue 接收消息。

幸运的是,我们重复了我们的队列声明,所以我们不需要担心队列存在的相关错误。

auto_ack 参数稍后将描述。

在某些情况下,我们会进入一个无限循环,等待数据并在必要时运行回调。在这种情况下,我们将处理 keyboardInterrupt 错误。

让我们看看下面的代码片段。

现在是时候把我们所有的代码放在一起以获得更多的理解了。

send.py

Receive.py

现在我们在终端中运行上面的脚本。首先,让我们启动一个消费者,它将持续运行等待消息传递。

输出

Waiting for messages. To exit press CTRL + C. 

现在在终端中启动生产者。生产者程序将在每次运行后停止。

消费者将打印

Waiting for messages. To exit press CTRL+C
Received 'Hello World!'

恭喜,我们成功通过 RabbitMQ 发送了第一条消息。

在本教程中,我们学习了如何从命名队列发送和接收消息。

结论

本教程包含使用 Python 编程语言实现 RabbitMQ 的指南。除此之外,我们还讨论了 RabbitMQ 的介绍以及我们为什么使用它。遵循本指南,我们将了解基本功能和流程。其余的您可以查阅官方文档以获取有关 RabbitMQ 的更多见解。其文档编写得很好,并附有适当的示例。