Rabbitmq - 延迟插件实现延迟队列

生产者

<?php
require_once __DIR__ . '/vendor/autoload.php';

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

$v_host = 'test';
$exc_name = 'delay_exc'; //交换器名
$routing_key = 'delay_routicg_key';
$queue_name = 'delay_queue';
$ttl = 20000; //必须为整数型,不可加引号 毫秒单位
//地址 端口 用户名 密码 vhost
$connection = new AMQPStreamConnection('localhost', 5672, 'rabbitmq', 'rabbitmq', $v_host);

//新建通道
$channel = $connection->channel();
//注:该类型的交换器需要先手动在管理端创建,否则报错
//声明交换器 参数:交换器名、模式、不存在则自动创建、持久化、不自动消亡
$channel->exchange_declare($exc_name, 'x-delayed-message', false, true, false);

$args = new AMQPTable(['x-delayed-type' => 'direct']);
//声明队列
$channel->queue_declare($queue_name, false, true, false, false, false, $args);
//队列绑定交换器
$channel->queue_bind($queue_name, $exc_name, $routing_key);

//设置消息持久化以及过期时间
$arr = ['delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT, 'application_headers' => new AMQPTable(['x-delay' => $ttl])];
$data = 'this is 20s delay message';
$msg = new AMQPMessage($data, $arr);
//将消息推送到交换器里
$channel->basic_publish($msg, $exc_name, $routing_key);

//设置消息持久化以及过期时间
$arr['application_headers'] = 10000;
$data = 'this is 10s delay message';
$msg = new AMQPMessage($data, $arr);
//将消息推送到交换器里
$channel->basic_publish($msg, $exc_name, $routing_key);


//关闭通道
$channel->close();
$connection->close();

消费者

<?php
require_once __DIR__ . '/vendor/autoload.php';

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

$v_host = 'test';
$exc_name = 'delay_exc'; //交换器名
$routing_key = 'delay_routicg_key';
$queue_name = 'delay_queue';
//地址 端口 用户名 密码 vhost
$connection = new AMQPStreamConnection('localhost', 5672, 'rabbitmq', 'rabbitmq', $v_host);

//新建通道
$channel = $connection->channel();
//声明交换器 参数:交换器名、模式、不存在则自动创建、持久化、不自动消亡
$channel->exchange_declare($exc_name, 'x-delayed-message', false, true, false);
// $channel->queue_declare($dead_queue_name, false, false, true, false);

$channel->queue_bind($queue_name, $exc_name, $routing_key);

$callback = function ($msg) {
    var_dump('received :' . $msg->body);
    $msg->ack();
};
//一次只消费一条消息,未确认消费前不可消费其他消息
$channel->basic_qos(null, 1, null);

$channel->basic_consume($queue_name, '', false, false, false, false, $callback);

while ($channel->is_open()) {
    $channel->wait();
}
//关闭通道
$channel->close();

注意点

延迟插件类型的交换器需手动在管理端创建

若未创建则报以下错误

posted @ 2022-08-30 10:26  Myifb  阅读(98)  评论(0)    收藏  举报