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


一、Work Queues?

队列默认按顺序将message发给下一个consumer.每个cosumer会获取到相同数量的的消息.
在这里插入图片描述

二、使用步骤

1.发送端new_task.php

代码如下(示例):

<?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.接收客户端

代码如下(示例):

<?php
	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.....

结果:
在这里插入图片描述
在这里插入图片描述
该结果表示队列是循环按顺序发给下一个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一个任务,直到它完成并给队列做出回应,才会发送下一个任务


总结

提示:未完待续

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值