RabbitMQ tutorial-one-php

简介

RabbitMQ 是一个 message broker: 它接收并转发消息。可以把它想象为一个邮局:你把信件放到邮箱里面,信件最终会被邮递员投送到目的地。类比的讲,RabbitMQ就是一个邮箱,一个邮局,一个邮递员。
RabbitMQ与邮局最大的不同是它并不处理纸质对象,它接收,储存并转发二进制数据块,也就是消息(messages)。
RabbitMQ和一般消息传递,有很专业术语。

  • 生产意味着仅仅发送消息,专门用来发送消息的程序叫做生产者。
    在这里插入图片描述
  • 队列是RabbitMQ里面的一个模块,像邮箱一样。尽管消息流在RabbitMQ和你的应用中传递,但是消息流仅仅只能保存在一个队列中。一个队列仅仅受限于服务端的内存和硬盘限制,它本质上是一个消息缓存;多个生产者可以发送消息到一个队列,多个消费者也可以从一个队列中接收消息。
    在这里插入图片描述
  • 消费和接收差不多,消费者程序要做的就是等待和接收消息;
    在这里插入图片描述
    需要注意的是,生产者,消费者和RabbitMQ并不是部署在同一台服务器上的。事实上,很多应用都不是部署在同一侧的。并且同时,一个应用可以同时是生产者,并且同时即是消费者。

“Hello World”

(using the php-amqplib Client)

在这段教程里面我们会用PHP写两段程序,一个生产者发送简单的消息,一个消费者接收消息并把他们打印出来。我们主要去实现hello world的发送和接收,不会太多探讨php-amqplibAPI的细节。
在下面简图中,P是生产者,C是消费者。中间的是消息队列,是RabbitMQ针对消费者保持的一个消息缓存。
在这里插入图片描述
PHP里面使用composer导入php-amqplib/php-amqplib类库。
在composer.json里面加入

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

执行导入

composer.phar install

导入类库之后,我们就可以编写代码了。

Sending

在这里插入图片描述
设置消息发送为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连接,并且处理了底层协议等。这里我们连接的是本地的RabbitMQ,如果想要连接别的RabbitMQ,只需要更换ip即可。
下面我们创建一个channel,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();

send.php完整代码

Receiving

消费者监听RabbitMQ的message,不像生产者一样仅仅发送一条消息,我们让消费者一直监听消息队列,然后把消息打印出来。
在这里插入图片描述
首先像生产者一样加载类库。

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

建立和生产者一样,我们开启一个连接和一个channel,并且声明一个要消费的队列。队列要和生产者队列一样。

$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();
}

只要channel有callback闭包函数,程序会阻塞。当从服务端接收一个消息之后,callback闭包函数会接收到消息。
receive.php完整代码

Putting it all together

同时运行两个脚本。
运行消费者

php receive.php

运行生产者

php send.php

消费者会打印出他从RabbitMQ接收到的所有消息。消费者会一直运行等待消费消息。

监听队列
如果想看到RabbitMQ的队列列表,并查看里面有多少条消息,可以使用rabbitmqctl工具查看。

sudo rabbitmqctl list_queues

在windows可以这样查看

rabbitmqctl.bat list_queues

官方链接:https://www.rabbitmq.com/tutorials/tutorial-one-php.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章