PHP Rabbitmq demo示例

一、生产者

//SendQuee.php
public function handle()
{
	//1.0 建立生产者与mq之间的连接
	$conn = new AMQPStreamConnection(
	   getenv('RB_HOST'),
	   getenv('RB_PORT'),
	   getenv('RB_USER'),
	   getenv('RB_PWD'),
	   getenv('RB_VHOST')
	);
	
	//2.0 已连接基础上建立生产者与mq之间的通道
	$channel = $conn->channel();
	
	//3.1 声明初始化交换机
	$channel->exchange_declare(getenv('RB_EXCHANGE'), getenv('RB_TYPE'), false, true, false); 
	//3.2 声明初始化一条队列
	$channel->queue_declare(getenv('RB_QUEUE_CZ'), false, true, false, false, false);
	//3.3 将队列与交换机进行绑定,并使用路由关键字
	$channel->queue_bind(getenv('RB_QUEUE_CZ'), getenv('RB_EXCHANGE'), getenv('RB_ROUTING_KEY'));
	
	//4.0 推送队列
	for($i=0; $i<=5; $i++){
	   $array = ["a$i"=>1, "b$i"=>2, "c$i"=>3];
	   $data  = json_encode($array);
	   //生成消息
	   $msg = new AMQPMessage($data);
	   $channel->basic_publish($msg, getenv('RB_EXCHANGE'), getenv('RB_ROUTING_KEY'));
	}
	
	//5.0 关闭
	$channel->close();
	$conn->close();
}

二、消费者

public function handle()
{
    $this->basic_get();
}

public function basic_get()
{
	//1.0 建立消费者与mq之间的连接
	$conn = new AMQPStreamConnection(
	    getenv('RB_HOST'),
	    getenv('RB_PORT'),
	    getenv('RB_USER'),
	    getenv('RB_PWD'),
	    getenv('RB_VHOST')
	);
	$channel = $conn->channel();
	
	//2.0 已连接基础上建立消费者与mq之间的通道
	$channel = $conn->channel();
	
	//3.1 声明初始化交换机
	$channel->exchange_declare(getenv('RB_EXCHANGE'), getenv('RB_TYPE'), false, true, false); 
	//3.2 声明初始化一条队列
	$channel->queue_declare(getenv('RB_QUEUE_CZ'), false, true, false, false, false);
	//3.3 绑定
	$channel->queue_bind(getenv('RB_QUEUE_CZ'), getenv('RB_EXCHANGE'), getenv('RB_ROUTING_KEY'));
	 
	//4.0 消费
	for($i=1; $i<200; $i++){
		/**
		 * @param string $queue 队列名称
		 * @param bool $no_ack 是否自动回复:true:自动回复;false:手动回复
		 **/
		$message = $channel->basic_get(getenv('RB_QUEUE_1_CZ'));
		if(!isset($message->body)) break;
		
		\Log::info("第 ".$message->delivery_info['delivery_tag']." 个 消息:".$message->body);
		
		//手动 ack 消息
		$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
	}
	
	//5.0 关闭连接
	$channel->close();
	$conn->close(); 
}

public function basic_consume()
{

	 //1.0 连接 Rabbitmq
	 $conn = new AMQPStreamConnection(
	    getenv('RB_HOST'),
	    getenv('RB_PORT'),
	    getenv('RB_USER'),
	    getenv('RB_PWD'),
	    getenv('RB_VHOST')
	);
	$channel = $conn->channel();
	
	//2.0 连接channel
	$channel = $conn->channel();
	
	//3.1 声明初始化交换机
	$channel->exchange_declare(getenv('RB_EXCHANGE'), getenv('RB_TYPE'), false, true, false); 
	//3.2 声明初始化一条队列
	$channel->queue_declare(getenv('RB_QUEUE_CZ'), false, true, false, false, false);
	//3.3 绑定
	$channel->queue_bind(getenv('RB_QUEUE_CZ'), getenv('RB_EXCHANGE'), getenv('RB_ROUTING_KEY'));
	
	$callback = function($message){
	    \Log::info("第 ".$message->delivery_info['delivery_tag']." 个 消息:".$message->body);
	    //手动 ack 消息
	    $message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
	};
	/**
	 * @param string $queue 队列名称
	 * @param string $consumer_tag 消费者标签,用来标识消费者的,在监听队列时设置
	 * @param bool $no_local
	 * @param bool $no_ack  是否自动回复:true:自动回复;false:手动回复
	 * @param bool $exclusive 
	 * @param bool $nowait
	 * @param callable|null $callback
	 **/
	$channel->basic_consume(getenv('RB_QUEUE_CZ'), '', false, true, false, false, $callback);
	
	while(count($channel->callbacks)) {
	    $channel->wait();
	}
	
	//6.0 关闭连接
	$channel->close();
	$conn->close();
}

在RabbitMQ中消费者有2种方式获取队列中的消息:

a) 一种是通过basic.consume命令,订阅某一个队列中的消息,channel会自动在处理完上一条消息之后,接收下一条消息。(同一个channel消息处理是串行的)。除非关闭channel或者取消订阅,否则客户端将会一直接收队列的消息。

b) 另外一种方式是通过basic.get命令主动获取队列中的消息,但是绝对不可以通过循环调用basic.get来代替basic.consume,这是因为basic.get在实际执行的时候,是首先consume某一个队列,然后检索第一条消息,然后再取消订阅。如果是高吞吐率的消费者,最好还是建议使用basic.consume。

简单总结一下就是说:
consume是只要队列里面还有消息就一直取。
get是只取了队列里面的第一条消息。

因为get开销大,如果需要从一个队列取消息的话,首选consume方式,慎用循环get方式。

参考资料:
RabbitMQ BasicGet与BasicConsume的区别
php-amqplib库操作RabbitMQ
Springboot 整合RabbitMq ,用心看完这一篇就够了
深入解析RabbitMQ消息应答ack机制
RabbitMq初探——消息确认

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值