在Fastadmin 简单使用RabbitMQ队列实现消息的收发
目录
[配置 RabbitMQ 连接信息](#配置 RabbitMQ 连接信息)
[封装 RabbitMQ 基础类](#封装 RabbitMQ 基础类)
[步骤 1:创建消费者命令](#步骤 1:创建消费者命令)
[步骤 2:注册命令](#步骤 2:注册命令)
[步骤 3:启动消费者](#步骤 3:启动消费者)
在php中进行消息的收发
在 PHP 中操作 RabbitMQ 需要借助php-amqplib扩展,以下是通过 PHP 代码实现消息收发(生产者和消费者)的详细步骤:
安装依赖库
安装php-amqplib
使用 Composer 安装php-amqplib(RabbitMQ 的 PHP 客户端库):
bash
composer require php-amqplib/php-amqplib

问题:最高只能安装到2.8版本,使用的rabbitmq链接代码较为落后。
安装提示:Cannot use php-amqplib/php-amqplib's latest version v3.7.3 as it requires ext-sockets * which is missing from your platform.
解决问题:
这个错误提示说明:php-amqplib v3.7.3 依赖 PHP 的 ext-sockets 扩展,但你的 PHP 环境中没有启用该扩展,导致安装失败。
安装ext-sockets扩展
手动开启
Windows 下的 PHP 通常已预编译 sockets 扩展,只需手动启用:
找到 PHP 的配置文件 php.ini:
打开 php.ini,搜索 extension=sockets:
若找到该行且前面有 ;(注释),去掉 ; 即可(如 ;extension=sockets → extension=sockets)。
若未找到,直接添加一行:extension=sockets(注意:PHP 7.0+ 通常不需要加 php_ 前缀,旧版本可能是 extension=php_sockets.dll)。
保存文件,重启 Web 服务器(如 Apache、Nginx)或 PHP 进程。
小皮面板
在网站列表,找到相应网站,选择php扩展,找到sockets打开,然后重启服务即可。

扩展如下:

重新安装依赖库
先卸载安装的2.8版本 php-amqplib/php-amqplib
bash
composer remove php-amqplib/php-amqplib
这次安装的版本为3.7,如下:

配置 RabbitMQ 连接信息
在application/config.php文件下新增rabbitmq配置文件,存放连接参数:
php
// +----------------------------------------------------------------------
// | Rabbit设置
// +----------------------------------------------------------------------
'rabbit' => [
// RabbitMQ主机
'host' => '127.0.0.1',
// 端口
'port' => 5672,
// 用户名(默认guest,仅本地访问)
'user' => 'guest',
// 密码
'password' => 'guest',
// 虚拟主机
'vhost' => '/',
// 心跳检测时间(秒)
'heartbeat' => 60,
// 默认队列名称
'queue' => [
'default' => 'fastadmin_default_queue',
]
],
封装 RabbitMQ 基础类
创建基础工具类处理连接、通道和队列声明,减少重复代码。
在application/common/library目录下新建RabbitMQ.php:
php
<?php
namespace app\common\library;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
use think\Config;
class RabbitMQ
{
protected $connection; // 连接对象
protected $channel; // 通道对象
protected $config; // 配置参数
public function __construct()
{
$this->config = Config::get('rabbitmq');
$this->connect();
}
// 建立连接
protected function connect()
{
try {
$this->connection = new AMQPStreamConnection(
$this->config['host'],
$this->config['port'],
$this->config['user'],
$this->config['password'],
$this->config['vhost'],
false,
'AMQPLAIN',
null,
'en_US',
$this->config['heartbeat'],
null
);
$this->channel = $this->connection->channel();
} catch (\Exception $e) {
throw new \Exception("RabbitMQ连接失败:" . $e->getMessage());
}
}
// 声明队列(确保队列存在)
public function declareQueue($queueName = null)
{
$queue = $queueName ?: $this->config['queue']['default'];
// 参数:队列名、是否持久化、是否排他、是否自动删除、其他参数
$this->channel->queue_declare($queue, false, true, false, false);
return $queue;
}
// 发送消息到队列
public function send($data, $queueName = null)
{
$queue = $this->declareQueue($queueName);
$message = new AMQPMessage(
json_encode($data, JSON_UNESCAPED_UNICODE),
['delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT] // 消息持久化
);
$this->channel->basic_publish($message, '', $queue);
}
// 消费消息(回调处理)
public function consume($callback, $queueName = null)
{
$queue = $this->declareQueue($queueName);
// 参数:队列名、消费者标签、是否自动确认、是否排他、是否本地、是否阻塞、回调函数
$this->channel->basic_consume($queue, '', false, false, false, false, $callback);
// 循环监听消息
while ($this->channel->is_consuming()) {
$this->channel->wait();
}
}
// 关闭连接
public function close()
{
if ($this->channel) {
$this->channel->close();
}
if ($this->connection) {
$this->connection->close();
}
}
// 析构函数自动关闭连接
public function __destruct()
{
$this->close();
}
}
实现生产者(发送消息)
在业务逻辑中调用RabbitMQ类发送消息到队列(例如控制器中):
在api/Demo.php中新增sendMessage方法,如下:
php
// 示例:发送消息到队列
public function sendMessage()
{
try {
$rabbitMQ = new RabbitMQ();
// 发送的数据(数组格式)
$data = [
'id' => 123,
'content' => '这是一条测试消息',
'time' => date('Y-m-d H:i:s')
];
// 发送到默认队列(也可指定队列名:$rabbitMQ->send($data, 'custom_queue'))
$rabbitMQ->send($data);
return '消息发送成功';
} catch (\Exception $e) {
return '发送失败:' . $e->getMessage();
}
}
实现消费者(处理消息)
消费者需持续运行监听队列,建议通过命令行脚本实现(FastAdmin 基于 ThinkPHP 的命令行机制)。
步骤 1:创建消费者命令
在application/common/command目录下新建RabbitMQConsumer.php:
php
<?php
namespace app\common\command;
use app\common\library\RabbitMQ;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Log;
class RabbitMQConsumer extends Command
{
// 配置命令
protected function configure()
{
$this->setName('rabbitmq:consumer') // 命令名:php think rabbitmq:consumer
->setDescription('RabbitMQ消费者,处理队列消息');
}
// 执行命令
protected function execute(Input $input, Output $output)
{
$output->writeln('消费者启动成功,开始监听队列...');
try {
$rabbitMQ = new RabbitMQ();
// 消息处理回调函数
$callback = function ($msg) use ($output) {
$output->writeln('收到消息:' . $msg->body);
// 解析消息(原发送的数组)
$data = json_decode($msg->body, true);
if (empty($data)) {
$output->writeln('消息格式错误');
$msg->nack(false, false); // 拒绝消息,不重新入队
return;
}
// 业务处理逻辑(例如:发送邮件、生成报表等)
try {
// TODO: 这里写具体的处理代码
$output->writeln('处理成功:' . $data['id']);
$msg->ack(); // 确认消息已处理(从队列删除)
} catch (\Exception $e) {
Log::error('消息处理失败:' . $e->getMessage());
$msg->nack(false, true); // 处理失败,重新入队(可限制重试次数)
}
};
// 监听默认队列(可指定队列名:$rabbitMQ->consume($callback, 'custom_queue'))
$rabbitMQ->consume($callback);
} catch (\Exception $e) {
$output->writeln('消费者异常:' . $e->getMessage());
Log::error('消费者异常:' . $e->getMessage());
}
}
}
步骤 2:注册命令
在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\RabbitMQConsumer', # 消费者
];
步骤 3:启动消费者
在项目根目录执行命令启动消费者:
bash
php think rabbitmq:consumer
若需在后台运行(生产环境),可结合supervisor管理进程(确保进程意外退出后自动重启)。
效果如下:

测试验证
访问http://你的域名/api/demo/sendMessage发送测试消息。
查看消费者控制台输出,应显示 "收到消息" 和处理结果。
请求效果:

处理效果:

若处理失败,消息会重新入队(根据nack参数配置)。
注意事项
消息持久化:队列和消息均需设置持久化(已在基础类中配置),避免 RabbitMQ 重启后消息丢失。
错误处理:消费者需捕获业务异常,通过ack()/nack()控制消息状态,避免死循环。
性能优化:生产环境可根据需求调整消费者数量(多个进程同时消费),或使用交换机(Exchange)分发消息到不同队列。
权限问题:默认guest用户仅允许本地访问,远程连接需创建新用户并授权(通过 RabbitMQ 管理界面:http://ip:15672)。
总结
在Fastadmin 简单使用RabbitMQ队列实现消息的收发