[译]PHP使用RabbitMQ文档--Hello World

这是一篇翻译在PHP中如何使用RabbitMQ的文档。有些地方加了一些自己的理解,但意思应该不差。本人水平有限,如有翻译不当还请谅解。

英文地址:RabbitMQ tutorial - "Hello World!" — RabbitMQ

介绍

RabbitMQ是一个消息代理,它接收和转发消息,你可以把它当做邮局。当您要发出的邮件放在邮箱中时,您的身份可以是先生或者女士,邮递员最终会把这封邮件发送到您的收件人。在这个比喻中,RabbitMQ是一个邮局、邮箱、快递员。

RabbitMQ和邮局之间的区别在于,它处理的方式不是纸张,而是接受,存储和转发二进制数据-消息。
RabbitMQ和一般的消息传递使用了一些术语:

  • 生产只意味着发送,发送消息的程序是一个生产者;

  • 队列是RabbitMQ中邮箱的名称。虽然消息流经RabbitMQ和您的程序,但他们只是存储在队列中。A队列仅由主机的存储器和磁盘限制约束,它本质上是一个比较大的消息缓冲器。多个生产者可以发送消息到队列,多个消费者也可以同时从队列中接收数据。这就是我们代表队列的方式

  • 消费和接收意思相近,一个消费者是一个程序,主要作用是等待接收消息

注意:生产者,消费者和代理不必在同一台主机上,实际上在大多数应用程序中也不是这样,应用程序也可以是生产者和消费者。

Hello World

(使用php-amqplib客户端)
在本教程的这一部分中,我们将编写两个程序,一个生产者用来发送单个消息,一个消费者接收消息并打印。我们将忽略php-amqplib API中的一些细节,专注于这个简单的开始。
在下图中,P是我们的生产者,C是我们的消费者,中间的红框是一个队列--RabbitMQ代表消费者的消息缓冲区。

one.png

php-amqplib客户端库
RabbitMQ有多种协议。本教程介绍了AMQP 0-9-1,它是一种开放的,通用的消息传递协议。RabbitMQ有多种不同语言的客户端,我们在本教程使用php-amqplib,并使用composer进行依赖管理。

将一个composer文件添加到你的项目中:

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

假如你已经安装composer并且运行正常,你可以运行下面的命令:

composer.phar install

也有适用于windows的composer安装程序;
现在我们也已经安装了php-amqplib库,现在我们可以写一些代码:

发送

sending.png

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

在send.php中,我们需要包含库并且use必要的类:

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

然后我们可以创建到服务器的连接:

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

这个连接抽象(abstracts )socket连接,并为我们负责协议版本协商和身份验证等。我们连接到本地代理--本地主机(localhost),如果我们想要连接到其他主机,我们只需要指定名称或ip地址即可。
下一步我们创建一个通道(channel),这是完成大多数任务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();

这是在github上的send.php代码

发送失败

如果你是第一次使用RabbitMQ并且运行失败,也许你会抓耳挠腮想到底是哪里出了问题。也许代理启动时没有足够的磁盘空间(默认情况下RabbitMQ至少需要200M磁盘空间)因此拒绝接收消息。这时候你需要检查日志文件并相应的减少一些限制,此配置文档会教你如何设置disk_free_limit

接收

这是我们的消息发布者。我们的接收者正在监听来自于RabbitMQ的消息,因此与发布单个消息的发布者不同,我们将持续运行监听消息并打印出来。

receiving.png

代码包含和引用的文件几乎和send.php相同:

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

和发布者的代码设置一样,我们打开一个连接(connection)和一个通道(channel),并声明我们要监听的队列,注意,这里监听的队列要和send.php中的队列一致。

$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";

注意,我们在这里也声明了队列,因为我们要确保在发布者运行之前先启动消费者。我们尝试消费消息之前要确认队列是否存在。

我们将告诉服务器从队列向我们传递消息,我们将定义一个回调函数,来接收从服务器接收到的消息。请记住,消息是从服务器异步发送到客户端的。

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

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

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

我们设置$channel阻塞运行并等待。每当我们收到一条消息时,我们的回调函数$callback将传递收到的消息。

这是在github上receive.php代码

运行

现在我们运行这两个文件。在终端中,运行消费者(接收者):

php receive.php

然后运行发布者:

php send.php

消费脚本(receive.php)将通过RabbitMQ获取并打印发布者发送的消息,接收者将持续运行,等待消息(使用ctrl + c)退出,尝试用另外一个终端运行send.php

列出队列

你也许想知道RabbitMQ上有多少个队列以及他们中有多少条消息,你可以使用rabbitmqctl工具:

sudo rabbitmqctl list_queues

windows上命令如下(进入bin目录):

rabbitmqctl.bat list_queues

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

生产[非]适用性免责声明

请记住,本教程和其他教程一样都是教程。他们一次只展示一个概念,可能会过度简化而忽略其他事项。例如,为了简洁起见,在很大程度上省略了像连接管理,错误处理,连接恢复,并发等问题。这种简化的代码并不代表可以生产使用了。

在使用程序之前,请先查看其它文档。我们特别推荐以下指南:发布者确认和消费致谢生产检查表监控

获得帮助并提供反馈

如果您对本教程或者RabbitMQ其它方面有疑问,请不要犹豫,在RabbitMQ邮箱列表中咨询他们。

帮助我们改进文档

如果你想对网站做出改进,可以在GitHub找到它的来源,fork一个仓库,并提交拉取请求即可。谢谢!