RabbitMQ配置延迟队列插件 rabbitmq_delayed_message_exchange

linux下直接安装
插件官方下载地址:https://www.rabbitmq.com/community-plugins.html
1.通过 rpm -qa|grep rabbit 命令查看当前linux是否安装RabbitMQ

[root@VM-8-4-centos ~]# rpm -qa|grep rabbit
rabbitmq-server-3.12.4-1.el8.noarch

2.通过 rpm -ql rabbitmq-server-3.12.4-1.el8.noarch 查找RabbitMQ安装路径
3.先通过 rabbitmq-plugins list 查看已安装的插件列表
4.进入/usr/lib/rabbitmq/lib/rabbitmq_server-3.12.4/plugins 目录上传下载好的rabbitmq_delayed_message_exchange插件(rabbitmq_delayed_message_exchange-4.0.2.ez)
5.启动插件 rabbitmq-plugins enable rabbitmq_delayed_message_exchange
6.重启RabbitMQ 使插件生效: service rabbitmq-server restart

在使用php发送延迟消息时遇到的问题
配置完后使用php作为发送端发送延迟消息发现 发送的消息没有延迟效果 我是用的php扩展是 php-amqplib

这是发送延迟消息但是并没有延迟效果的代码
  public static function delayPush2($queue, $exchange, $routing_key, $messageBody, $delayTime)
    {
        // 获取连接
        $connection = self::getConnect();

        // 构建通道(mq的数据存储与获取是通过通道进行数据传输的)
        $channel = $connection->channel();

        // 指定交换机,若是路由的名称不匹配不会把数据放入队列中
        $channel->exchange_declare(
            $exchange,
            'x-delayed-message', // 使用延迟交换机类型
            false, // passive
            true,  // durable
            false, // auto_delete
            false, // internal
            false, // nowait
            ['x-delayed-type' => ['S', 'direct']], // 正确:
        );

        // 声明一个队列
        $channel->queue_declare($queue, false, true, false, false);

        // 队列和交换器绑定/绑定队列和类型
        $channel->queue_bind($queue, $exchange, $routing_key);

        $headers = ['x-delay' => $delayTime * 1000];
        // 配置消息
        $config = array(
            'content_type' => 'text/plain',
            'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT,
            'headers' => $headers  // 延迟时间(毫秒)
        );

        // 实例化消息推送类
        $message = new AMQPMessage($messageBody, $config);

        // 消息推送到路由名称为 $exchange 的队列当中
        $channel->basic_publish($message, $exchange, $routing_key);

        // 关闭消息推送资源
        $channel->close();
        // 关闭 mq 资源
        $connection->close();
    }

经过一个上午的派查 发现导致没有延迟的原因是在声明交换器的时候传参的格式有问题
如果你使用的是 php-amqplib/php-amqplib 库,那么设置交换机属性时需要使用 AMQPTable 类型来定义属性,而不是直接使用关联数组。
` // 设置交换机属性
$args = new AMQPTable();
$args->set('x-delayed-type', 'direct');

// 指定交换机,确保使用 AMQPTable 传递属性
$channel->exchange_declare(
    $exchange,
    'x-delayed-message',
    false,    // passive
    true,     // durable
    false,    // auto_delete
    false,    // internal
    false,    // nowait
    $args     // 使用 AMQPTable 传递属性
);`
下面是完整的发送端方法
 public static function delayPush($queue, $exchange, $routing_key, $messageBody, $delayTime)
    {
        // 获取连接
        $connection = self::getConnect();

        // 构建通道
        $channel = $connection->channel();

        // 设置交换机属性
        $args = new AMQPTable();
        $args->set('x-delayed-type', 'direct');

        // 指定交换机,确保使用 AMQPTable 传递属性
        $channel->exchange_declare(
            $exchange,
            'x-delayed-message',
            false,    // passive
            true,     // durable
            false,    // auto_delete
            false,    // internal
            false,    // nowait
            $args     // 使用 AMQPTable 传递属性
        );

        // 声明一个队列
        $channel->queue_declare($queue, false, true, false, false);

        // 队列和交换器绑定
        $channel->queue_bind($queue, $exchange, $routing_key);

        // 配置消息
        $headers = new AMQPTable(['x-delay' => intval($delayTime)]); // 使用 AMQPTable
        $config = [
            'content_type' => 'text/plain',
            'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT,
            'application_headers' => $headers // 使用 'application_headers' 而不是 'headers'
        ];

        // 实例化消息推送类
        $message = new AMQPMessage($messageBody, $config);

        // 消息推送到路由名称为 $exchange 的队列当中
        $channel->basic_publish($message, $exchange, $routing_key);

        // 关闭消息推送资源
        $channel->close();

        // 关闭 mq 资源
        $connection->close();
    }

本文作者:hasse

本文链接:https://www.cnblogs.com/spinachead/articles/18540054

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   hasse  阅读(505)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
🔑