工作队列
在第一篇教程中,我们已经写了一个从已知队列中发送和获取消息的程序。在这篇教程中,我们将创建一个工作队列(Work Queue),它会发送一些耗时的任务给多个工作者(Works )。
工作队列(又称:任务队列——Task Queues)是为了避免等待一些占用大量资源、时间的操作。当我们把任务(Task)当作消息发送到队列中,一个运行在后台的工作者(worker)进程就会取出任务然后处理。当你运行多个工作者(workers),任务就会在它们之间共享。
这个概念在网络应用中是非常有用的,它可以在短暂的HTTP请求中处理一些复杂的任务。
准备
之前的教程中,我们发送了一个包含“Hello World!”的字符串消息。现在,我们将发送一些字符串,把这些字符串当作复杂的任务。我们没有真是的例子,例如图片缩放、pdf文件转换。所以使用 sleep()函数来模拟这种情况。我们在字符串中加上点号(.)来表示任务的复杂程度,一个点(.)将会耗时1秒钟。比 如”Hello…”就会耗时3秒钟。
我们对之前教程的send.php做些简单的调整,以便可以发送随意的消息。这个程序会按照计划发送任务到我们的工作队列中。我们把它命名为new_task.php:
1 |
$message = empty ( $argv [1]) ? 'Hello World!' : ' ' . $argv [1]; |
2 |
$exchange ->publish( $message , $routeKey ); |
3 |
var_dump( "[x] Sent $message" ); |
我们的旧脚本(receive.php)同样需要做一些改动:它需要为消息体中每一个点号(.)模拟1秒钟的操作。它会从队列中获取消息并执行,我们把它命名为worker.php:
1 |
function callback( $envelope , $queue ) {
|
2 |
$msg = $envelope ->getBody(); |
3 |
var_dump( " [x] Received:" . $msg ); |
4 |
sleep(substr_count( $msg , '.' )); |
5 |
$queue ->ack( $envelope ->getDeliveryTag()); |
轮询分发
使用工作队列的一个好处就是它能够并行的处理队列。如果堆积了很多任务,我们只需要添加更多的工作者(workers)就可以了,扩展很简单。
首先,我们先同时运行两个worker.php脚本,它们都会从队列中获取消息,到底是不是这样呢?我们看看。
你需要打开三个终端,两个用来运行worker.php脚本,这两个终端就是我们的两个消费者(consumers)—— C1 和 C2。
shell1
2 |
[*] Waiting for messages. To exit press CTRL+C |
shell2
2 |
[*] Waiting for messages. To exit press CTRL+C |
第三个终端,我们用来发布新任务。你可以发送一些消息给消费者(consumers):
shell3
1 |
$ php new_task.php First message. |
shell3
1 |
$ php new_task.php Second message.. |
shell3
1 |
$ php new_task.php Third message... |
shell3