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

Laravel Horizon中失败任务未自动重试问题排查求助

问题:Laravel Horizon 任务失败后不自动重试

我有一个SendEmailMessage任务,已设置public $tries = 2;,但任务失败后并未自动重试,只能在Horizon中手动重试。

任务代码

class SendEmailMessage implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $message;
    public $tries = 2;

    public function __construct(EmailMessage $message)
    {
        $this->message = $message;
    }

    public function handle(EmailMessageRepository $emailMessageRepository)
    {
        app()->setLocale($this->message->organization->locale);
        $emailMessageRepository->send($this->message);
    }
}

队列配置

'email' => [
    'driver' => 'redis',
    'connection' => 'default',
    'queue' => 'email',
    'retry_after' => 90,
    'block_for' => null,
],

Horizon Supervisor配置

'supervisor-2' => [
    'connection' => 'redis',
    'queue' => ['media', 'email', 'sms'],
    'balance' => 'simple',
    'processes' => 1,
    'tries' => 2,
],

排查与解决思路

  • 检查异常是否被捕获吞掉
    Laravel队列仅会对未被捕获的异常触发自动重试。如果$emailMessageRepository->send()方法内部捕获了邮件发送相关的异常(比如连接超时、服务器错误)但没有重新抛出,任务会被标记为执行成功,自然不会触发重试。需要确保发送逻辑中的异常能够冒泡到任务的handle方法外。

  • 确认retry_after配置逻辑
    队列的retry_after设置为90秒,这个参数是当任务执行时长超过90秒时,Laravel会判定任务超时失败并重新入队。如果你的任务是在90秒内抛出异常,这个配置不影响重试,但如果任务执行时间过长导致被强制标记失败,需要确保该值大于任务正常执行的最大时长。

  • 验证Horizon配置是否生效
    Horizon Supervisor中的tries配置优先级高于任务类的tries,但你两者都设置为2,所以数值上没有冲突。需要确认Horizon是否已重启,确保新的配置被加载(可以执行php artisan horizon:terminate后重新启动Horizon)。

  • 查看任务失败详情
    在Horizon的失败任务列表中查看任务的执行次数和失败原因:如果任务已经执行了2次(初始执行+1次重试)后进入失败列表,说明重试逻辑正常;如果仅执行1次就失败,那还是异常未触发重试的问题。

  • 检查Horizon Worker状态
    执行php artisan horizon:status确认worker进程是否正常运行,若进程卡住或未启动,重启Horizon即可。


内容的提问来源于stack exchange,提问作者Martin Drapeau

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 12:30:15