线上环境 队列功能 驱动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秒到底是什么地方出现了问题,求赐教,谢谢。

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案

这个问题为什么会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年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!