RabbitMQ 入门 - Hello World

基于 官方文档 翻译

介绍

RabbitMQ 是一个消息代理:它接受和转发消息。 你可以把它想象成一个邮局:当你把你想要发布的邮件放在邮箱中时,你可以确定邮差先生最终将邮件发送给你的收件人。 在这个比喻中,RabbitMQ是邮政信箱,邮局和邮递员。

RabbitMQ 和邮局的主要区别在于它不处理纸张,而是接受、存储和转发二进制数据块 - 消息

RabbitMQ 和一般的消息传递使用了一些术语。

  • Producing 意味着发送。 A 程序是一个发送消息的生产者( producer):

    img

  • A queue( 队列)是 RabbitMQ 中邮箱的名称。 尽管消息流经过 RabbitMQ 和您的应用程序,但它们只能存储在队列中。 一个队列只受主机内存和磁盘限制的约束,它本质上是一个很大的消息缓冲区。 许多生产者可以发送进入一个队列的消息,并且许多消费者可以尝试从一个队列接收数据。 这就是我们代表队列的方式:

    img

  • Consuming (消费) 类似于接受的意思。 消费者是一个等待接收消息的主程序:

    img

请注意 producerconsumerbroker 不必驻留在同一主机上(实际上在大多数应用程序中也不会这么做)。

"Hello World"

(使用 php-amqplib 客户端)

​ 在本教程的这一部分,我们将使用PHP编写两个程序;一个发送单个消息的生产者,以及接收消息并将其打印出来的消费者。我们将讨论 php-amqplib API 中的一些细节,把注意力集中在这个简单的事情上。这是一个消息传递的 “Hello World”。在下图中,P 是我们的生产者,C 是我们的消费者。中间的框是一个队列—— RabbitMQ 代表消费者保存的消息缓冲区。

img

php-amqplib 库

RabbitMQ 提供多种协议。本教程涵盖了 AMQP 0-9-1,它是一种开放、通用的消息传递协议。有许多不同语言的 RabbitMQ 客户端。我们将在本教程中使用 php-amqplib ,并使用 Composer 进行依赖性管理。

Add a composer.json file to your project:

{
   "require": {
       "php-amqplib/php-amqplib": ">=2.6.1"
   }
}

如果您安装了 Composer 并且功能正常,则可以运行以下操作:

composer.phar install

还有一个适用于 Windows 的 Composer 安装程序。

现在我们安装了 php-amqplib 库,我们可以编写一些代码。

Sending(发送)

img

我们会调用我们的消息发布者(sender)send.php 和我们的消息接收者 receive.php。 发布者将连接到RabbitMQ,发送一条消息,然后退出。

send.php 中,我们需要包含库并使用必要的类:

require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

那么我们可以创建一个到服务器的连接:

$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();

连接抽象出套接字连接(socket),并为我们处理协议版本协商和身份验证等。在这里,我们连接到本地机器上的代理 - 因此是 localhost。如果我们想连接到另一台机器上的代理,我们只需在此指定其名称或 IP 地址。

接下来我们创建一个频道,这是大部分用于完成任务的 API 驻留的地方。

接下来是发送,由于我们必须声明一个队列去为我们发送,那么我们可以将消息发布到队列中:

$channel->queue_declare('hello', false, false, false, false);

$msg = new AMQPMessage('Hello World!');
$channel->basic_publish($msg, '', 'hello');

echo " [x] Sent 'Hello World!'\n";

声明一个队列是幂等的 - 只有当它不存在时才会被创建。消息内容是一个字节数组,所以你可以输入任何你喜欢的内容。

最后,我们关闭频道和连接;

$channel->close();
$connection->close();

Here's the whole send.php class.

发送不起作用!

如果这是你第一次使用 RabbitMQ,并且你没有看到“已发送”消息,那么你可能会抓住您的脑袋,想知道会出现什么问题。 也许代理启动时没有足够的可用磁盘空间(默认情况下它至少需要200 MB空闲空间),因此拒绝接受消息。 检查代理日志文件以确认并在必要时减少限制。配置文件文档将告诉你如何设置 disk_free_limit。

Receiving(接收)

这是我们的消费者。我们将接收从 RabbitMQ 推送的消息,因此与发布单个消息的发布者不同,我们将持续运行以收听消息并将其打印出来。

img

代码内容(在 receive.php 中)与 send 有相同的包含和用法:

require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;

设置与发布者相同; 我们打开一个连接和一个通道,并声明我们将要使用的队列。 注意,这与发送发布的队列匹配。

$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();

$channel->queue_declare('hello', false, false, false, false);

echo ' [*] Waiting for messages. To exit press CTRL+C', "\n";

请注意,我们也在这里声明队列。 因为我们可能会在发布者之前启动消费者,所以我们希望在我们尝试使用消息之前确保队列已存在。

我们即将告诉服务器将队列中的消息传递给我们。 我们将定义一个 PHP 可调用函数 ,它将接收服务器发送的消息。 请记住,消息是从服务器异步发送到客户端。

$callback = function($msg) {
 echo " [x] Received ", $msg->body, "\n";
};

$channel->basic_consume('hello', '', false, true, false, false, $callback);

while(count($channel->callbacks)) {
   $channel->wait();
}

我们的代码会阻塞,而我们的回调函数会传递收到的消息。

Here's the whole receive.php class

把它们放在一起

现在我们可以运行这两个脚本。 在终端中,运行消费者(receiver):

php receive.php

然后运行发布者(sender):

php send.php

消费者将打印它通过 RabbitMQ 从发件人获得的消息。 接收器将持续运行,等待消息(使用Ctrl-C将其停止),因此请尝试从其他终端运行发送器。

队列监听

您可能希望看到 RabbitMQ 有什么队列以及它们中有多少条消息。 您可以使用 rabbitmqctl 工具(作为特权用户)执行此操作:

sudo rabbitmqctl list_queues

在 Windows 上,省略 sudo:

rabbitmqctl.bat list_queues

是时候转到第2部分并构建一个简单的工作队列。

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 6年前 自动加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 10
php炎黄

收藏了 希望大佬坚持下去

6年前 评论
yanrui

:+1:

6年前 评论

收藏了111111

5年前 评论

收藏了 哈哈哈哈哈

5年前 评论

收藏了 希望大佬坚持下去

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!