thinkphp6实战Rabbitmq之延时队列(完整篇)

本文详细介绍了如何在ThinkPHP6框架中实战使用Rabbitmq实现延时队列。首先,通过下载并安装rabbitmq的延迟消息交换器插件,然后在docker容器中启用该插件并重启服务。接着,创建交换器,编写消费端和生产端脚本,并在项目的配置文件中注册命令。此外,还涉及了php-amqplib的安装,以及rabbitmq配置文件的创建。最后,展示了控制器发布任务后的效果。

1.安装延迟队列插件rabbitmq-delayed-message-exchange

https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases

在这里插入图片描述

1.拷贝到对应rabbitmq容器中

docker cp rabbitmq_delayed_message_exchange-3.10.2.ez  rabbitmq:/plugins

2.进入容器

docker exec -it 容器id /bin/bash

3.启用插件

rabbitmq-plugins enable rabbitmq_delayed_message_exchange

4.重新启动容器

docker restart 容器id

2.创建交换器
在这里插入图片描述
3.创建消费端脚本

php think make:command Ccomer comer

4.在项目 config/console.php 中的’commands’注册命令

<?php
 return [
  'commands' => [
        'comer' => \app\command\Comer::class,
  ]
];

5.安装php-amqplib插件

composer require php-amqplib/php-amqplib

6.config文件夹下新建rabbitmq.php文件rabbitMQ配置

<?php

return [

    'AMQP' => [
        'host' => '127.0.0.1',
        'port'=>'5672',
        'login'=>'guest',
        'password'=>'guest',
        'vhost'=>'/'
    ],

    'email_queue' => [
        'exchange_name' => 'delay-queue',
        'exchange_type'=>'direct',
        'queue_name' => 'email_queue',
        'route_key' => 'email_roteking',
        'consumer_tag' => 'consumer'
    ],
    
];

7.创建生产端逻辑

<?php
namespace app\controller;

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

class MqProducer 
{
    public static function pushMessage($data,$ttl)
    {
        $param = config('rabbitmq.AMQP');
        $amqpDetail = config('rabbitmq.email_queue');
        $connection = new AMQPStreamConnection($param['host'],$param['port'],$param['login'],$param['password'],$param['vhost']);
        $channel = $connection->channel();

        $channel->exchange_declare($amqpDetail['exchange_name'], 'x-delayed-message', false, true, false);
        $args = new AMQPTable(['x-delayed-type' => 'direct']);
        $channel->queue_declare($amqpDetail['queue_name'], false, true, false, false,$args);


        $arr = ['delivery_mode' => AMQPMEssage::DELIVERY_MODE_PERSISTENT, 'application_headers' => new AMQPTable(['x-delay' => $ttl])];

        $data = json_encode($data);
        $message = new AMQPMessage($data, $arr);
        $channel->basic_publish($message, $amqpDetail['exchange_name'],$amqpDetail['route_key']);
        $channel->close();
        $connection->close();
        return true;
    }

}

7.创建消费端逻辑

<?php
namespace app\controller;

use PhpAmqpLib\Connection\AMQPStreamConnection;
use think\Controller;

class MqConsumer
{
    /**
     * 消费端 消费端需要保持运行状态实现方式
     * 1 linux上写定时任务每隔5分钟运行下该脚本,保证访问服务器的ip比较平缓,不至于崩溃
     * 2 nohup php index.php index/Message_Consume/start &  用nohup命令后台运行该脚本
     * 3
     **/
    function shutdown($channel, $connection)
    {
        $channel->close();
        $connection->close();
    }

    function process_message($message)
    {


        echo  date('Y-m-d H:i:s').":".json_encode($message->body)."\n";

        $message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
        if ($message->body === 'quit') {
            $message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']);
        }
    }

    /**
     * 启动
     * @return \think\Response
     */
    public function start()
    {
        $param = config('rabbitmq.AMQP');
        $amqpDetail = config('rabbitmq.email_queue');
        $connection = new AMQPStreamConnection(
            $param['host'],
            $param['port'],
            $param['login'],
            $param['password'],
            $param['vhost']
        );

        $channel = $connection->channel();
        $channel->queue_declare($amqpDetail['queue_name'], false, true, false, false);
        $channel->exchange_declare($amqpDetail['exchange_name'], 'x-delayed-message', false, true, false);
        $channel->queue_bind($amqpDetail['queue_name'], $amqpDetail['exchange_name'], $amqpDetail['route_key']);


        $channel->basic_consume($amqpDetail['queue_name'], $amqpDetail['consumer_tag'], false, false, false, false, array($this, 'process_message'));
        register_shutdown_function(array($this, 'shutdown'), $channel, $connection);
        while (count($channel->callbacks)) {
            $channel->wait();
        }
    }


}

8.控制器发布任务

    public function send()
    {
        $consumer = new MqProducer();
        $data = [
            'time'=>date('Y-m-d H:i:s'),
            'email1'=>rand(1,100),
        ];
        $rt = $consumer->pushMessage($data,10*1000);//毫秒
        return json(['status'=>$rt,'data'=>date('Y-m-d H:i:s')]);
    }

最终效果
在这里插入图片描述图一

在这里插入图片描述图二

如图一页面出现rabbitmq: Management API returned status code 500

cd /etc/rabbitmq/conf.d/
echo management_agent.disable_metrics_collector = false > management_agent.disable_metrics_collector.conf
exit
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值