这是一篇翻译在PHP中如何使用RabbitMQ的文档。有些地方加了一些自己的理解,但意思应该不差。本人水平有限,如有翻译不当还请谅解。
英文地址:RabbitMQ tutorial - "Hello World!" — RabbitMQ
介绍
RabbitMQ是一个消息代理,它接收和转发消息,你可以把它当做邮局。当您要发出的邮件放在邮箱中时,您的身份可以是先生或者女士,邮递员最终会把这封邮件发送到您的收件人。在这个比喻中,RabbitMQ是一个邮局、邮箱、快递员。
RabbitMQ和邮局之间的区别在于,它处理的方式不是纸张,而是接受,存储和转发二进制数据-消息。
RabbitMQ和一般的消息传递使用了一些术语:
生产只意味着发送,发送消息的程序是一个生产者;
队列是RabbitMQ中邮箱的名称。虽然消息流经RabbitMQ和您的程序,但他们只是存储在队列中。A队列仅由主机的存储器和磁盘限制约束,它本质上是一个比较大的消息缓冲器。多个生产者可以发送消息到队列,多个消费者也可以同时从队列中接收数据。这就是我们代表队列的方式
消费和接收意思相近,一个消费者是一个程序,主要作用是等待接收消息
注意:生产者,消费者和代理不必在同一台主机上,实际上在大多数应用程序中也不是这样,应用程序也可以是生产者和消费者。
Hello World
(使用php-amqplib客户端)
在本教程的这一部分中,我们将编写两个程序,一个生产者用来发送单个消息,一个消费者接收消息并打印。我们将忽略php-amqplib API中的一些细节,专注于这个简单的开始。
在下图中,P是我们的生产者,C是我们的消费者,中间的红框是一个队列--RabbitMQ代表消费者的消息缓冲区。
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库,现在我们可以写一些代码:
发送
我们将调用我们的消息发布者(发送者)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();
发送失败
如果你是第一次使用RabbitMQ并且运行失败,也许你会抓耳挠腮想到底是哪里出了问题。也许代理启动时没有足够的磁盘空间(默认情况下RabbitMQ至少需要200M磁盘空间)因此拒绝接收消息。这时候你需要检查日志文件并相应的减少一些限制,此配置文档会教你如何设置disk_free_limit
。
接收
这是我们的消息发布者。我们的接收者正在监听来自于RabbitMQ的消息,因此与发布单个消息的发布者不同,我们将持续运行监听消息并打印出来。
代码包含和引用的文件几乎和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
将传递收到的消息。
运行
现在我们运行这两个文件。在终端中,运行消费者(接收者):
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一个仓库,并提交拉取请求即可。谢谢!