You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Horizon 拾取作业延迟1-2秒问题排查求助

针对Horizon作业拾取延迟的优化方案

直接调用handle是同步执行,没有队列调度开销,而Horizon的延迟主要来自队列监听策略、进程配置、Redis交互这几个环节。结合你的配置,可从以下方向调整:


1. 调整队列进程的负载均衡策略

你当前用的balance => 'auto'会根据队列长度动态调进程数,但调整有冷却时间,突发小量请求可能来不及扩容。建议:

  • 对低延迟需求的supervisor-fast-jobs,把balance改成'simple',避免动态调整的开销:
    'supervisor-fast-jobs' => [
        // ... 其他配置保留
        'balance' => 'simple', // 固定分配进程到队列,无动态调整延迟
    ]
    
  • 缩短balanceCooldown时间(生产环境当前是3秒),改成1秒让进程调整更灵敏:
    'balanceCooldown' => 1,
    

2. 增加最小进程数,避免冷启动延迟

生产环境下你的minProcesses都是1,无作业时进程会缩到1,新作业进来要等扩容。对supervisor-fast-jobs这类队列,直接设置minProcesses为日常最小需求数:

'supervisor-fast-jobs' => [
    'minProcesses' => 5, // 根据业务量调整,避免进程从零启动
    'maxProcesses' => 150,
    // ... 其他配置
]

3. 优化Redis队列的阻塞监听配置

Redis队列默认是阻塞式读取,但如果配置了sleep参数,空闲时进程会休眠,新作业进来要等休眠结束。检查config/queue.php的Redis连接:

'redis' => [
    'driver' => 'redis',
    'connection' => 'default',
    'queue' => env('REDIS_QUEUE', 'default'),
    'retry_after' => 90,
    'block_for' => null, // 设为null表示无限阻塞,有作业立即响应
],

4. 确保作业投递到正确的快速队列

控制器触发作业时,明确指定redis-short-running或on-demand-runs-now这类快速队列:

// 控制器代码示例
YourJob::dispatch()->onQueue('redis-short-running');

如果默认投到default队列(属于regular-jobs),进程优先级和数量都不如快速队列,必然有延迟。

5. 降低Horizon监控开销

你的配置开启了metrics,如果不需要实时监控,可减少快照保留数量:

'metrics' => [
    'trim_snapshots' => [
        'job' => 24, // 减少到24小时
        'queue' => 24,
    ],
]

同时确保目标作业在silenced列表里,避免Horizon记录过多日志拖慢速度。

6. 优化Redis连接性能

  • 确保Redis和应用在同一服务器,避免跨网络延迟
  • 在config/database.php的Redis配置里开启持久化连接,减少TCP握手开销:
    'redis' => [
        'default' => [
            // ... 其他配置
            'persistent' => true, // 开启持久化连接
        ],
    ]
    

7. 调整进程重启策略

当前maxTime设置(比如fast队列60秒)会让进程每60秒重启一次,频繁重启会导致拾取延迟。可延长maxTime或设置maxJobs:

'supervisor-fast-jobs' => [
    'maxTime' => 300, // 改成5分钟
    'maxJobs' => 1000, // 处理1000个作业后重启,平衡内存泄漏和重启频率
]

8. 开启Fast Termination

当前fast_termination是false,开启后Horizon重启时无需等待所有进程结束,新进程可立即处理作业,减少部署/重启时的延迟:

'fast_termination' => true,

验证步骤

调整配置后重启Horizon:

php artisan horizon:terminate
php artisan horizon

再用Carbon记录从dispatch到handle开始的时间差,对比延迟是否减少。

内容的提问来源于stack exchange,提问作者Ryan H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 03:18:11