RabbitMQ-PHP(1)工作队列,分发任务给不同的的消费者

文章目录

  • 一、Work Queues?
  • 二、使用步骤
    • 1.发送端new_task.php
    • 2.接收客户端
    • 3.执行结果
    • 4.要点分析
  • 总结


一、Work Queues?

队列默认按顺序将message发给下一个consumer.每个cosumer会获取到相同数量的的消息.
RabbitMQ-PHP(1)工作队列,分发任务给不同的的消费者_第1张图片

二、使用步骤

1.发送端new_task.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();
	$channel->queue_declare('task_queue', false, true, false, false);
	
	$data = implode(' ', array_slice($argv,1));
	if(empty($data)){
     
		$data = "Hello World!";
	}
	
	
		
		$msg = new AMQPMessage($data,
		 array('delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT)
		);
	
		$channel->basic_publish($msg, '', 'task_queue');
	
	
	echo '[x]Sent',$data,'\n';

2.接收客户端

代码如下(示例):


	require_once(__DIR__ . './vendor/autoload.php');
	use PhpAmqpLib\Connection\AMQPStreamConnection;
	
	$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
	$channel = $connection->channel();
	
	$channel->queue_declare('task_queue', false, true, false, false);
	
	echo " [*] Waiting for messages. To exit press CTRL+C\n";
	
	$callback = function ($msg) {
     
	  echo ' [x] Received ', $msg->body, "\n";
	  sleep(substr_count($msg->body, '.'));
	  echo " [x] Done\n";
	  $msg->ack();
	};
	
	
	$channel->basic_qos(null, 1, null);
	$channel->basic_consume('task_queue', '', false, false, false, false, $callback);
	
	while ($channel->is_open()) {
     
	    $channel->wait();
	}
	
	 
	$channel->close();
	$connection->close();

3.执行结果

分别运行 两个 worker.php,一个new_task.php

# shell 1
php worker.php
# shell 2
php worker.php
# shell 3
php new_task.php First message.
php new_task.php Second message..
php new_task.php Third message...
php new_task.php Fourth message....
php new_task.php Fifth message.....

结果:
RabbitMQ-PHP(1)工作队列,分发任务给不同的的消费者_第2张图片
在这里插入图片描述
该结果表示队列是循环按顺序发给下一个consumer.

4.要点分析

1.ack

basic_consume 第四个参数

该参数是针对ack的参数,true表示没有ack给队列,false表示我们consumer处理完消息后通过代码给队列发送确认已处理的消息;
代码为:

$callback = function ($msg) {
     
  echo ' [x] Received ', $msg->body, "\n";
  sleep(substr_count($msg->body, '.'));
  echo " [x] Done\n";
  $msg->ack();//该条代码为给队列做ack回应
};
$channel->basic_consume('task_queue', '', false, false, false, false, $callback);//第四个参数要设置为false

2.消息持久化

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

第三个参数
将该参数设置为true,即使我们重启MQ我们的列队也不会丢失.
然后我们还需要设置发送的消息持久,如下

$msg = new AMQPMessage(
    $data,
    array('delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT)
);

3.公平调度

$channel->basic_qos(null, 1, null);

当队列不停给consumer发送任务时,在consumer还没处理完上一个任务时,会使cosumer压力很大,进而影响整个系统,通过上面的设置,会限制每次只传送个同一个consumer一个任务,直到它完成并给队列做出回应,才会发送下一个任务


总结

提示:未完待续

你可能感兴趣的:(RabbitMQ,php,队列,php,rabbitmq)