Laravel 12 使用 RabbitMQ 作为消息队列驱动
在 Laravel 12 中使用 RabbitMQ 作为消息队列驱动需要安装额外的包,因为 Laravel 默认不包含 RabbitMQ 驱动。以下是完整的配置和使用指南:
安装依赖包
安装 RabbitMQ PHP 客户端和 Laravel 队列适配器:
composer require php-amqplib/php-amqplib
composer require vladimir-yuldashev/laravel-queue-rabbitmq
配置环境变量
在 .env
文件中添加 RabbitMQ 连接信息:
QUEUE_CONNECTION=rabbitmq
RABBITMQ_HOST=127.0.0.1
RABBITMQ_PORT=5672
RABBITMQ_USER=guest
RABBITMQ_PASSWORD=guest
RABBITMQ_VHOST=/
配置队列连接
在 config/queue.php
中添加 RabbitMQ 连接配置:
'connections' => [
// ... 其他连接配置
'rabbitmq' => [
'driver' => 'rabbitmq',
'queue' => env('RABBITMQ_QUEUE', 'default'),
'connection' => PhpAmqpLib\Connection\AMQPLazyConnection::class,
'hosts' => [
[
'host' => env('RABBITMQ_HOST', '127.0.0.1'),
'port' => env('RABBITMQ_PORT', 5672),
'user' => env('RABBITMQ_USER', 'guest'),
'password' => env('RABBITMQ_PASSWORD', 'guest'),
'vhost' => env('RABBITMQ_VHOST', '/'),
],
],
'options' => [
'ssl_options' => [
'cafile' => env('RABBITMQ_SSL_CAFILE', null),
'local_cert' => env('RABBITMQ_SSL_LOCALCERT', null),
'local_key' => env('RABBITMQ_SSL_LOCALKEY', null),
'verify_peer' => env('RABBITMQ_SSL_VERIFY_PEER', true),
'passphrase' => env('RABBITMQ_SSL_PASSPHRASE', null),
],
'queue' => [
'job' => VladimirYuldashev\LaravelQueueRabbitMQ\Queue\Jobs\RabbitMQJob::class,
],
],
/*
* 设置工作队列参数
*/
'worker' => env('RABBITMQ_WORKER', 'default'),
// 高级交换机配置
'exchange' => [
'name' => env('RABBITMQ_EXCHANGE_NAME', 'laravel_exchange'),
'type' => env('RABBITMQ_EXCHANGE_TYPE', 'direct'), // direct, topic, fanout, headers
'passive' => env('RABBITMQ_EXCHANGE_PASSIVE', false),
'durable' => env('RABBITMQ_EXCHANGE_DURABLE', true),
'auto_delete' => env('RABBITMQ_EXCHANGE_AUTO_DELETE', false),
],
// 高级队列配置
'queue_params' => [
'passive' => env('RABBITMQ_QUEUE_PASSIVE', false),
'durable' => env('RABBITMQ_QUEUE_DURABLE', true),
'exclusive' => env('RABBITMQ_QUEUE_EXCLUSIVE', false),
'auto_delete' => env('RABBITMQ_QUEUE_AUTO_DELETE', false),
'arguments' => env('RABBITMQ_QUEUE_ARGUMENTS', '[]'),
],
// 绑定配置
'bindings' => [
[
'queue' => env('RABBITMQ_QUEUE', 'default'),
'routing_key' => env('RABBITMQ_ROUTING_KEY', 'default.key'),
],
],
],
],
创建队列任务
php artisan make:job ProcessOrder
编辑 app/Jobs/ProcessOrder.php
:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessOrder implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $orderData;
public function __construct(array $orderData)
{
$this->orderData = $orderData;
}
public function handle()
{
// 处理订单逻辑
\Log::info('Processing order: ' . json_encode($this->orderData));
// 模拟任务处理
sleep(2);
\Log::info('Order processed successfully');
}
// 任务失败处理
public function failed(\Throwable $exception)
{
\Log::error('Order processing failed: ' . $exception->getMessage());
}
}
分发任务到 RabbitMQ
在控制器中分发任务:
use App\Jobs\ProcessOrder;
// 分发到默认队列
ProcessOrder::dispatch([
'order_id' => 12345,
'customer' => 'John Doe',
'amount' => 99.99
]);
// 分发到指定队列
ProcessOrder::dispatch([
'order_id' => 67890,
'customer' => 'Jane Smith',
'amount' => 149.99
])->onQueue('priority_orders');
// 延迟分发任务(10分钟后执行)
ProcessOrder::dispatch([
'order_id' => 54321,
'customer' => 'Bob Johnson',
'amount' => 49.99
])->delay(now()->addMinutes(10));
启动队列 Worker
# 监听默认队列
php artisan queue:work rabbitmq
# 监听指定队列
php artisan queue:work rabbitmq --queue=priority_orders,default
# 带有重试机制的 Worker
php artisan queue:work rabbitmq --tries=3 --timeout=30
# 使用多个 Worker 进程
php artisan queue:work rabbitmq --queue=priority_orders --tries=3 --timeout=30 &
php artisan queue:work rabbitmq --queue=default --tries=3 --timeout=30 &
生产环境使用 Supervisor
创建 /etc/supervisor/conf.d/laravel-rabbitmq.conf
:
[program:laravel-rabbitmq-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/your-project/artisan queue:work rabbitmq --sleep=3 --tries=3 --max-jobs=1000
autostart=true
autorestart=true
user=www-data
numprocs=8
redirect_stderr=true
stdout_logfile=/var/www/your-project/storage/logs/worker.log
stopwaitsecs=60
管理 Supervisor:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-rabbitmq-worker:*
高级配置选项
交换机类型
在 .env
中配置不同的交换机类型:
# 直连交换机(默认)
RABBITMQ_EXCHANGE_TYPE=direct
# 主题交换机(支持通配符匹配)
RABBITMQ_EXCHANGE_TYPE=topic
# 扇出交换机(广播到所有队列)
RABBITMQ_EXCHANGE_TYPE=fanout
# 头交换机(基于消息头路由)
RABBITMQ_EXCHANGE_TYPE=headers
死信队列配置
添加死信队列支持:
'queue_params' => [
'arguments' => [
'x-dead-letter-exchange' => 'dead_letters',
'x-dead-letter-routing-key' => 'dead_letter_key',
],
],
// 单独配置死信队列
'dead_letter_queue' => [
'name' => 'dead_letters',
'exchange' => 'dead_letters',
'routing_key' => 'dead_letter_key',
],
优先级队列
配置优先级队列:
'queue_params' => [
'arguments' => [
'x-max-priority' => 10, // 设置优先级范围 (1-255)
],
],
分发优先级任务:
ProcessOrder::dispatch($data)->onQueue('high_priority')->rabbitmqPriority(10);
监控 RabbitMQ
使用 RabbitMQ 管理插件(默认端口 15672):
# 启用管理插件
RABBITMQ_MANAGEMENT=1
# 自定义管理端口
RABBITMQ_MANAGEMENT_PORT=15672
在浏览器中访问:http://your-server:15672
常见问题解决
连接问题
-
无法连接 RabbitMQ:
- 检查防火墙设置:
sudo ufw allow 5672/tcp
- 验证 RabbitMQ 服务状态:
sudo systemctl status rabbitmq-server
- 检查用户权限:
sudo rabbitmqctl list_users
- 检查防火墙设置:
-
SSL 连接问题:
RABBITMQ_SSL_VERIFY_PEER=false
性能优化
-
预取计数:
php artisan queue:work rabbitmq --prefetch=10
-
禁用序列化模型:
// 在任务类中 public $preserveModel = false;
-
批量处理消息:
php artisan queue:work rabbitmq --batch=100
高级使用场景
延迟消息队列
配置延迟队列插件:
# 启用 RabbitMQ 延迟消息插件
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
在 .env
中配置:
RABBITMQ_EXCHANGE_TYPE=x-delayed-message
RABBITMQ_EXCHANGE_ARGUMENTS={"x-delayed-type":"direct"}
分发延迟消息:
ProcessOrder::dispatch($data)
->delay(now()->addMinutes(30))
->onQueue('delayed_queue');
RPC 模式(请求-响应)
创建 RPC 任务:
class RpcProcessOrder implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $correlationId;
public function __construct(public array $orderData)
{
$this->correlationId = Str::uuid()->toString();
}
public function handle()
{
// 处理逻辑...
return ['status' => 'success'];
}
}
发起 RPC 请求并等待响应:
use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\RabbitMQQueue;
$response = app(RabbitMQQueue::class)->rpc(
new RpcProcessOrder($data),
'rpc_queue',
30 // 超时时间(秒)
);
完整控制器示例
namespace App\Http\Controllers;
use App\Jobs\ProcessOrder;
use Illuminate\Http\Request;
class OrderController extends Controller
{
public function createOrder(Request $request)
{
$data = $request->validate([
'customer' => 'required|string',
'items' => 'required|array',
'total' => 'required|numeric'
]);
$orderId = uniqid('ORD_');
// 分发订单处理任务
ProcessOrder::dispatch([
'order_id' => $orderId,
'customer' => $data['customer'],
'items' => $data['items'],
'total' => $data['total'],
'timestamp' => now()->toDateTimeString()
])->onQueue('order_processing');
// 分发后续通知任务
ProcessOrder::dispatch([
'order_id' => $orderId,
'customer' => $data['customer'],
'action' => 'send_confirmation'
])->delay(now()->addMinutes(5))
->onQueue('notifications');
return response()->json([
'status' => 'pending',
'message' => 'Order is being processed',
'order_id' => $orderId
]);
}
}
总结
通过以上配置,您可以在 Laravel 12 中成功使用 RabbitMQ 作为消息队列驱动。RabbitMQ 提供了强大的消息路由、持久化、确认机制和高级消息模式,非常适合需要高可靠性和复杂消息处理场景的应用。
关键优势:
- 支持多种交换机类型和路由模式
- 消息持久化和确认机制
- 优先级队列和延迟消息
- 死信队列和消息重试
- 高吞吐量和分布式处理能力
对于生产环境,建议:
- 使用 Supervisor 管理 Worker 进程
- 配置 RabbitMQ 集群实现高可用
- 启用 TLS 加密传输
- 实施合理的队列监控和警报
- 定期进行队列性能测试和优化