Fastadmin中通过RabbitMq实现即时和延迟队列

Fastadmin中通过RabbitMq实现即时和延迟队列消息

在原来实现基本队列消息的基础上,可以同时发送和消费即时、延迟两种队列消息。

目录

实现即时和延迟队列

修改配置

工具类实现

消费消息

即时消息消费者

延时消息消费者

注册任务队列

启动消费者

发送消息

总结


实现即时和延迟队列

修改配置

在配置文件中分开定义两种队列的参数,便于维护和扩展。

在application/config.php中修改原有的rabbitmq配置,如下:

php 复制代码
// +----------------------------------------------------------------------
// | Rabbitmq设置
// +----------------------------------------------------------------------
'rabbitmq'               => [
    // 基础配置
    // RabbitMQ主机
    'host'      => '127.0.0.1',
    // 端口
    'port'      => 5672,
    // 用户名(默认guest,仅本地访问)
    'user'      => 'guest',
    // 密码
    'password'  => 'guest',
    // 虚拟主机
    'vhost'     => '/',
    // 心跳检测时间(秒)
    'heartbeat' => 60,
    // 即时消息配置
    'immediate' => [
        // 即时交换机
        'exchange' => 'fastadmin_immediate_exchange',
        // 即时队列
        'queue' => 'fastadmin_immediate_queue',
        // 即时路由键
        'routing_key' => 'immediate_key'
    ],
    // 延迟队列相关配置
    'delay' => [
        // 临时队列(消息过期)
        'temp_queue' => 'fastadmin_delay_temp_queue',
        // 死信交换机
        'dlx_exchange' => 'fastadmin_delay_dlx_exchange',
        // 死信队列(最终消费)
        'dlx_queue' => 'fastadmin_delay_dlx_queue',
        // 死信路由键
        'dlx_routing_key' => 'delay_key'
    ]
],

工具类实现

RabbitMQ工具类中封装两种消息的声明、发送、消费方法,复用连接和通道资源。

在application/common/library/RabbitMQ.php中修改原有代码,整体如下:

消费消息

需要分别启动两个消费者进程(可通过命令行脚本实现)。

即时消息消费者

在application/common/command/目录下创建ConsumerImmediate.php文件,内容如下:

php 复制代码
<?php

namespace app\common\command;

use app\common\library\RabbitMQ;
use think\console\Command;
use think\console\Input;
use think\console\Output;

class ConsumerImmediate extends Command
{
    // 配置命令
    protected function configure()
    {
        $this->setName('consumer_immediate')  // 命令名:php think consumer_immediate
        ->setDescription('RabbitMQ消费者,处理队列即时消息');
    }

    // 执行命令
    protected function execute(Input $input, Output $output)
    {
        $output->writeln('消费者启动成功,开始监听队列...');
        try {
            $rabbitMQ = new RabbitMQ();
            $callback = function ($msg) {
                $data = json_decode($msg->body, true);
                echo "处理即时消息:" . $data['content'] . "(ID:{$data['id']})\n";
                $msg->ack(); // 手动确认
            };
            $rabbitMQ->consumeImmediate($callback);

        } catch (\Exception $e) {
            $output->writeln('消费者异常:' . $e->getMessage());
        }
    }
}
延时消息消费者

在application/common/command/目录下创建ConsumerDelay.php文件,内容如下:

php 复制代码
<?php

namespace app\common\command;

use app\common\library\RabbitMQ;
use think\console\Command;
use think\console\Input;
use think\console\Output;

class ConsumerDelay extends Command
{
    // 配置命令
    protected function configure()
    {
        $this->setName('consumer_delay')  // 命令名:php think consumer_delay
        ->setDescription('RabbitMQ消费者,处理队列延时消息');
    }

    // 执行命令
    protected function execute(Input $input, Output $output)
    {
        $output->writeln('延迟消息消费者启动,等待延迟消息...');
        try {
            $rabbitMQ = new RabbitMQ();
            $callback = function ($msg) {
                $data = json_decode($msg->body, true);
                echo "处理延迟消息:" . $data['content'] . "(ID:{$data['id']})\n";
                $msg->ack(); // 手动确认
            };
            $rabbitMQ->consumeDelay($callback);
        } catch (\Exception $e) {
            $output->writeln('消费者异常:' . $e->getMessage());
        }
    }
}
注册任务队列

在application/command.php中把即时消息消费者和延时消息消费者注册,如下:

php 复制代码
return [
    'app\admin\command\Crud',
    'app\admin\command\Menu',
    'app\admin\command\Install',
    'app\admin\command\Min',
    'app\admin\command\Addon',
    'app\admin\command\Api',
    'app\common\command\ConsumerImmediate',
    'app\common\command\ConsumerDelay',
];

启动消费者

打开两个终端,分别执行以下命令:

bash 复制代码
# 启动即时消息消费者
php think consumer_immediate

# 启动延迟消息消费者(另开终端)
php think consumer_delay

发送消息

在demo.php中编写两个发送消息方法,分别是即时消息和延迟消息,如下:

php 复制代码
// 示例:发送消息到队列
public function sendMessage()
{
    // 发送即时消息
    $rabbitMQ = new RabbitMQ();
    try {
        $rabbitMQ->sendImmediateMessage([
            'id'        => 1,
            'content'   => '这是一条即时消息',
            'time'      => date('Y-m-d H:i:s')
        ]);
        echo "即时消息发送成功\n";
    } catch (\Exception $e) {
        echo "即时消息发送失败:" . $e->getMessage() . "\n";
    }
}

// 示例:延迟 10 秒处理消息
public function sendDelay()
{
    $rabbitMQ = new RabbitMQ();
    try {
        $rabbitMQ->sendDelayMessage([
            'id'        => 2,
            'content'   => '这是一条延迟消息',
            'time'      => date('Y-m-d H:i:s')
        ], 10);
        echo "延迟消息发送成功\n";
    } catch (\Exception $e) {
        echo "延迟消息发送失败:" . $e->getMessage() . "\n";
    }
}

注意:fastadmin中要设置无需登录和授权。

然后分别发送两种消息,效果如下:

在linux中可以使用Supervisor监控队列执行,避免因意外崩溃导致消息堆积。

总结

Fastadmin中通过RabbitMq实现即时和延迟队列消息的完整版,使用其他框架也可以借此实现。

相关推荐
两个人的幸福10 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
BingoGo12 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack12 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户30745969820713 天前
PHP 扩展——从入门到理解
php
鹏仔先生14 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
云水一下14 天前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php
xingpanvip14 天前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
JLWcai2025100914 天前
铸造领域树脂砂轮|金利威多场景解决方案,20 + 配方覆盖全需求
mongodb·zookeeper·eureka·spark·rabbitmq·memcached·storm
酉鬼女又兒14 天前
零基础入门计算机网络运输层:端到端通信核心作用、端口号分类规则、复用分用工作机制及UDP与TCP协议全方位对比详解
网络·网络协议·tcp/ip·计算机网络·考研·udp·php
dog25014 天前
不要再继续优化 TCP
网络协议·tcp/ip·php