PHP RabbitMQ消息队列演示代码

先决条件

已安装PHP,Erlang和RabbitMQ。

安装PHP环境下使用的RabbitMQ第三方库——php-amqplib

使用composer安装php-amqplib库。

生产者代码

<?php
require 'vendor/autoload.php';

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Wire\AMQPTable;

$conf = [
    'host' => 'localhost',
    'port' => 5672,
    'user' => 'admin',
    'password' => 'admin',
    'vhost' => '/',
];
$exchangeName = 'testExch';     //交换机名称
$queueName = 'testQue';         //队列名称
$routingKey = 'testRoute';      //路由关键字(也可以省略)

//建立生产者与mq之间的连接
try {
    $conn = new AMQPStreamConnection($conf['host'], $conf['port'], $conf['user'], $conf['password'], $conf['vhost']);
} catch (\Exception $e) {
    exit("RabbitMQ连接失败。\n");
}

$channel = $conn->channel();    //在已连接基础上建立生产者与MQ之间的通道
$channel->exchange_declare($exchangeName, 'direct', false, true, false);    //声明初始化交换机

$args = new AMQPTable();
$args->set('x-message-ttl',10000);    //设置TTL,消息生存期(设置属性需要生产者和消费者同时设置)

$channel->queue_declare($queueName, false, true, false, false,false,$args);     //声明初始化一条队列
$channel->queue_bind($queueName, $exchangeName, $routingKey,false);       //将队列与某个交换机进行绑定,并使用路由关键字

// $channel->confirm_select();     //开启ACK,确认机制

for ($i = 1; $i <= 20; $i++) {
    $msgBody = json_encode(["name" => "WCW", "no" => $i]);
    $msg = new AMQPMessage($msgBody, ['content_type' => 'text/plain', 'delivery_mode' => 2]);   //构建消息
    $ret = $channel->basic_publish($msg, $exchangeName, $routingKey);     //发布消息到某个交换机
}

/*
// 若消息发布成功
$channel->set_ack_handler(function (AMQPMessage $msg){
    echo "消息发布成功 \n";
});
$channel->wait_for_pending_acks();      //等待ACK确认
*/

$channel->close();
$conn->close();

消费者代码

<?php
require 'vendor/autoload.php';

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Wire\AMQPTable;

$conf = [
    'host' => 'localhost',
    'port' => 5672,
    'user' => 'admin',
    'password' => 'admin',
    'vhost' => '/',
];
$exchangeName = 'testExch';     //交换机名
$queueName = 'testQue';         //队列名称
$routingKey = 'testRoute';      //路由关键字(也可以省略)

//建立生产者与mq之间的连接
try {
    $conn = new AMQPStreamConnection($conf['host'], $conf['port'], $conf['user'], $conf['password'], $conf['vhost']);
} catch (\Exception $e) {
    exit("RabbitMQ连接失败。\n");
}

$channel = $conn->channel();    //在已连接基础上建立生产者与MQ之间的通道

$args = new AMQPTable();
$args->set('x-message-ttl',10000);    //设置TTL,消息生存期(设置属性需要生产者和消费者同时设置)

$channel->queue_declare($queueName, false, true, false, false,false,$args);     //声明初始化一条队列

//消费限流,每次只能处理5条消息(在basic_consume的参数no_ask=false的情况下才生效)
$channel->basic_qos(null, 5, null);

//回调函数,数据处理
$process_message = function ($msg) {
    $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);     //消费限流,一轮消费完成后,告知生产者进行下一轮消息发布
    echo "Received: ", json_decode($msg->body)->no, "\n";
    // $msg->nack(true);
};

$channel->basic_consume($queueName, '', false, false, false, false, $process_message);      //消费接收消息

//监听消息,一有消息,立马就处理
/*while(count($channel->callbacks)) {
    $channel->wait();
}*/
//或:
while ($channel->is_consuming()) {
    $channel->wait();
    sleep(5);      //来让ACK即处理消息的过程慢一些,这样我们就可以从后台管理工具中清晰观察到限流情况
}

效果测试

执行生产者程序:

执行消费者程序:

消息接收成功!

 

至此。转载请注明出处,记得扫码打赏支持哦,谢谢!

 

posted @ 2021-05-03 21:17  失恋的蔷薇  阅读(419)  评论(0编辑  收藏  举报