线上环境 队列功能 驱动database 90S 必终止报错

1. 问题描述?#

线上环境使用 Supervisor,没有使用 Horizon 管理工具。 驱动:database 队列,超过 90S 以后就会报错即使任务已经失败,仍然在运行:

Illuminate\Queue\MaxAttemptsExceededException: App\Jobs\AiInstall has been attempted too many times. in /home/api/vendor/laravel/framework/src/Illuminate/Queue/Worker.php:785
Stack trace:
#0 /home/api/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(519): Illuminate\Queue\Worker->maxAttemptsExceededException()
#1 /home/api/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(429): Illuminate\Queue\Worker->markJobAsFailedIfAlreadyExceedsMaxAttempts()
#2 /home/api/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(389): Illuminate\Queue\Worker->process()
#3 /home/api/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(176): Illuminate\Queue\Worker->runJob()
#4 /home/api/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(138): Illuminate\Queue\Worker->daemon()
#5 /home/api/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(121): Illuminate\Queue\Console\WorkCommand->runWorker()
#6 /home/api/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\Queue\Console\WorkCommand->handle()
#7 /home/api/vendor/laravel/framework/src/Illuminate/Container/Util.php(41): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#8 /home/api/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\Container\Util::unwrapIfClosure()
#9 /home/api/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(37): Illuminate\Container\BoundMethod::callBoundMethod()
#10 /home/api/vendor/laravel/framework/src/Illuminate/Container/Container.php(662): Illuminate\Container\BoundMethod::call()
#11 /home/api/vendor/laravel/framework/src/Illuminate/Console/Command.php(208): Illuminate\Container\Container->call()
#12 /home/api/vendor/symfony/console/Command/Command.php(326): Illuminate\Console\Command->execute()
#13 /home/api/vendor/laravel/framework/src/Illuminate/Console/Command.php(178): Symfony\Component\Console\Command\Command->run()
#14 /home/api/vendor/symfony/console/Application.php(1081): Illuminate\Console\Command->run()
#15 /home/api/vendor/symfony/console/Application.php(320): Symfony\Component\Console\Application->doRunCommand()
#16 /home/api/vendor/symfony/console/Application.php(174): Symfony\Component\Console\Application->doRun()
#17 /home/api/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(201): Symfony\Component\Console\Application->run()
#18 /home/api/artisan(37): Illuminate\Foundation\Console\Kernel->handle()
#19 {main}

这是 Supervisor 配置:

[program:aiinstall]
process_name=%(program_name)s_%(process_num)02d
command=php /home/api/artisan queue:work --queue=aiinstall
autostart=true
autorestart=true
numprocs=1
redirect_stderr=true
stdout_logfile=/home/logs/log.log

我在 PHPstudy 本地操作,一个队列即使运行一个小时,仍然不会显示该报错
我尝试过在 config/queue.php 中修改驱动 database 的 retry_after 为 0

'database' => [
            'driver' => 'database',
            'table' => 'jobs',
            'queue' => 'default',
            'retry_after' => 0,
            'after_commit' => false,
        ],

也尝试过在队列代码里面把 timeout 设置为 0

public $timeout = 0;

加入队列代码:

AiInstall::dispatch($request->all())->onConnection('database')->onQueue('aiinstall');

日志仍然显示的是 90 秒到了,立刻再 RUNNING 一次,即使 FAIL。不知道是什么情况,再 FAIL 之后,他仍然会执行完当前队列剩下的任务(我没有设置处理 FAIL,他已经在 failed_jobs 表里面了,还是会继续执行),因为这个任务是 sql 添加语句,会在 FAIL 之后的任务里还会出现相同的数据生成两条的情况。
日志图片如下所述:
线上环境 database队列功能 90S timeout问题
当 $timeout 尝试设置过 36000S 时,当运行 90S 后,报错就是 time out 超时。。
我不太清楚这个 90 秒到底是什么地方出现了问题,求赐教,谢谢。

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
最佳答案

这个问题为什么会 90S 准时报错,是因为 config/queue.php 设置任务到期 retry_after 这个默认 90 的参数,我没有用:php artisan queue:restart 对其进行重启,导致任务一旦 90S 就 fail 问题到底是出自哪里。

虽然已经解决,但还是有点疑惑。希望后面遇见下面问题的朋友也可以告诉我,谢谢

1 为什么本地就无视了这个 90S 的任务到期的状态,我一个任务可以运行个把小时都没有问题,并且 queue.php 配置也是 90

2 在线上,超过 90S 的时间限制后,任务已经返回 fail。我没有对 fail 进行任何处理,也没有告诉他,失败后重新运行任务。为什么仍然会继续执行后面的任务,并且会执行完。是谁在继续执行后面的任务

1年前 评论
讨论数量: 15

报错的方法已经提示了错误原因 markJobAsFailedIfAlreadyExceedsMaxAttempts 。计划任务代码写的有问题

1年前 评论
csmarco (楼主) 1年前
deatil (作者) 1年前
deatil (作者) 1年前
随波逐流

检查下扩展 pcntl 是否安装

1年前 评论
csmarco (楼主) 1年前
随波逐流 (作者) 1年前
csmarco (楼主) 1年前

先手动跑一下代码看看有没有问题,排查一下是程序执行的问题还是队列的问题

1年前 评论
csmarco (楼主) 1年前

你没修改的话,使用默认,超过 90 秒然后进行重试正常呢,因为超过 90 秒就重新回队列去了
config/queue.php 的 retry_after 选项,不管使用数据库还是啥,都是默认 90
队列《Laravel 9 中文文档》
修改的方式有多种 参数也是好几个,自己认真看下队列相关文档

如果你的代码不需要执行超过 90 秒,你就优化你的代码,让其不要超过九十秒,如果一定会超过 90 秒,就修改相关配置

1年前 评论
csmarco (楼主) 1年前

这个问题为什么会 90S 准时报错,是因为 config/queue.php 设置任务到期 retry_after 这个默认 90 的参数,我没有用:php artisan queue:restart 对其进行重启,导致任务一旦 90S 就 fail 问题到底是出自哪里。

虽然已经解决,但还是有点疑惑。希望后面遇见下面问题的朋友也可以告诉我,谢谢

1 为什么本地就无视了这个 90S 的任务到期的状态,我一个任务可以运行个把小时都没有问题,并且 queue.php 配置也是 90

2 在线上,超过 90S 的时间限制后,任务已经返回 fail。我没有对 fail 进行任何处理,也没有告诉他,失败后重新运行任务。为什么仍然会继续执行后面的任务,并且会执行完。是谁在继续执行后面的任务

1年前 评论

可以尝试打印下队列内部执行的内存占用情况,如果代码没问题,可以从内存上分析一下,这种内存上的问题,是队列直接停止了,没有额外的报错

1年前 评论