Laravel Horizon 监控仪表盘
Horizon 是专为 Laravel + Redis 队列设计的监控仪表盘:实时查看任务处理速率、失败率、Worker 状态,还能配置多队列的 Worker 数量和优先级——告别"队列死了不知道"的尴尬。
安装
composer require laravel/horizon
php artisan horizon:install
# 发布 config/horizon.php 和前端资产
配置 horizon.php
// config/horizon.php
return [
'use' => 'default',
'prefix' => env('HORIZON_PREFIX', 'horizon:'),
// 生产环境:自动扩缩 Worker 数量
'environments' => [
'production' => [
// 邮件队列:固定 2 个 Worker
'emails' => [
'connection' => 'redis',
'queue' => ['emails'],
'balance' => 'simple', // simple / auto / false
'processes' => 2,
'tries' => 3,
'timeout' => 60,
],
// 默认队列:自动扩缩 1-5 个 Worker
'default' => [
'connection' => 'redis',
'queue' => ['default'],
'balance' => 'auto', // 根据队列深度自动调整
'minProcesses' => 1,
'maxProcesses' => 5,
'balanceMaxShift' => 1, // 每次最多增减 1 个 Worker
'balanceCooldown' => 3, // 调整间隔(秒)
'tries' => 3,
'timeout' => 90,
],
// 重型任务(视频转码、大文件处理)
'heavy' => [
'connection' => 'redis',
'queue' => ['heavy'],
'balance' => 'simple',
'processes' => 1, // 只用 1 个 Worker(避免 OOM)
'tries' => 1,
'timeout' => 1800, // 30 分钟超时
'memory' => 1024, // 限制最大内存 1GB
],
],
'local' => [
'local' => [
'connection' => 'redis',
'queue' => ['default', 'emails'],
'balance' => false,
'processes' => 1,
'tries' => 1,
],
],
],
];
启动 Horizon
# 开发/生产环境启动(替代 queue:work)
php artisan horizon
# 优雅停止(等待当前 Job 完成后退出)
php artisan horizon:terminate
# 暂停(不处理新 Job,保留 Worker 进程)
php artisan horizon:pause
php artisan horizon:continue
# 查看状态
php artisan horizon:status
; Supervisor 配置(生产环境)
; /etc/supervisor/conf.d/taskflow-horizon.conf
[program:taskflow-horizon]
process_name=%(program_name)s
command=php /var/www/taskflow/artisan horizon
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/var/www/taskflow/storage/logs/horizon.log
stopwaitsecs=3600 ; 给 Horizon 足够的时间完成当前任务
访问控制(生产环境)
// app/Providers/AppServiceProvider.php
use Laravel\Horizon\Horizon;
public function boot(): void
{
// 只允许管理员访问 /horizon 仪表盘
Horizon::auth(function ($request) {
return $request->user()?->hasRole('admin') ?? false;
});
// 失败任务告警(发送 Slack 通知)
Horizon::routeSlackNotificationsTo(
webhook: config('services.slack.webhook'),
channel: '#alerts'
);
// SMS 告警
Horizon::routeSmsNotificationsTo('+60112345678');
// 邮件告警
Horizon::routeMailNotificationsTo('admin@taskflow.app');
}
Horizon 仪表盘功能
访问 /horizon(需要认证):
🔴 Overview(概览):
- 活跃 Worker 数量
- 每分钟处理的任务数(throughput)
- 过去 1 小时/24 小时的任务统计
🔴 Monitoring(监控):
- 按队列查看深度(backlog)
- Worker 进程状态
🔴 Recent Jobs(最近任务):
- 所有最近执行的 Job
- 可以按状态过滤(完成/失败/等待)
🔴 Failed Jobs(失败任务):
- 失败原因、完整堆栈
- 一键重试
- 按失败时间排序
🔴 Batches(批处理):
- 批次进度
- 批次内的成功/失败数
Job 指标标签(Metrics)
// 在 Job 中添加 tags,方便在 Horizon 中按标签过滤
class ProcessPayment implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function tags(): array
{
return [
'payment',
'user:' . $this->order->user_id,
'order:' . $this->order->id,
];
}
}
下一章:事件、监听器与广播(Reverb)——队列处理了异步任务,事件系统解决了代码解耦问题:任务完成时,谁应该被通知?谁应该触发后续操作?Event/Listener 让业务逻辑不相互依赖。