关于 Laravel 队列经常卡死的问题。
使用队列的原因:因为项目需要每天定时拉取多个api的数据,数据量大(每次上万个任务),所以选择使用队列拉取。
工具:laravel队列,supervisor进程监控
遇到的问题:队列在运行过程中会突然卡住不再运行,需要重启horizon和supervisorctl,才会继续运行。
(2020-01-03 15:31:00补充)难点:手动运行正常!重启队列并观察,也正常!运行一段时间,队列卡住,只有重启才能运行
疑问:
一开始想着是否是自己的程序有问题,但是手动使用php artisan运行command来检测任务的时候,每次在horizon面板都是看着正常运行。而且每次宕机之后,去看horizon面板都是发现任务累积了很多,所以也不存在是因为队列没有任务,导致work挂掉(而且已使用Supervisor 进行监控)。
是否是说:laravel队列长时间运行之后,必须重启?因为有时候一两天内都是正常的,过几天突然就卡了。
关于日志:在horizon日志中:没有异常报错,比如一直processing循环这种,中断任务时候都是前面正常运行,后面突然就停止了(日志就中断了)。在failed_job中,报错基本都是job运行的次数过多或者时间过长
目前已采用的解决方案:
1、将任务分割为多个队列进程,第一为了不让某些任务影响到后续任务,第二方便定位问题并且重新手动运行任务,第三,不知是否是单一队列时,长时间运行被服务器自动kill进程
2、增加public $tries = 5;限制任务最大重试次数,避免任务重复被推进队列运行
3、将Eloquent 模型改为初始的DB::table()连接方式进行增删改查。
但是仍然无法解决,所以在此寻求帮助。感激不尽。
附上解决过程:
1、
使用背景:一开始任务不多,所以全部都是用default队列工作,导致任务卡死之后,只能所有任务都重新运行,
猜测:是否是任务过多,程序一直占用系统内存,导致被kill掉了
解决方案:因为对服务器的机制不太理解,猜测可能是系统内存不够时将进程终止了,也因为需要进队列的工作越来越多,方便调试和定位问题,所以将任务从default队列中分开来,使用多个队列运行不同类型(job)的任务。
2、
使用背景:已分割为多个任务,此时发现问题仍然存在,
找寻资料以及猜测:翻过资料,发现有可能是因为job中使用了Eloquent 模型,导致程序运行的时候,有时候无法检索到指定的模型,导致程序一直循环运行(中间查询failed_job以及log发现运行最大时间达到150s),
解决方案:将所有的job中使用模型的地方,全部使用DB::table()的初始方式来进行增删改查,并且增加public $tries = 5,限制重试次数。
结果:中间正确运行了几天,周末回来之后,发现任务再次中断。
3、
对于failed_job中的工作的测试,找到没有更新成功的数据,手动执行任务,除了中间调试语句出错的,剩下的报错信息是has been attempted too many times or run too long. The job may have previously timed out. 的任务,测试了有20个左右,都是成功的,
大家好,这个问题暂时不关闭了,期待有人能找到根源。
我现在的处理方案是,每天定时重启一次supervisorctl服务,并且每个job加上最长运行时间和最多重试次数,防止任务被重复推入队列,附上重启队列任务
0 16 * php /path/to/your/project/artisan horizon:terminate && sudo supervisorctl reload >> /dev/null 2>&1
首先给大家说声抱歉,最近都没看这边,导致问题一直没关闭,然后非常感谢各位的解答,我来说下我目前的处理方式吧。 首先,配置上进行了修改,将原先的队列进一步细分(不仅是为了让任务更快运行,也是保证不同板块的任务不会有干扰),如图:
其次,代码中增加最大运行次数(因为查日志,发现部分任务失败后一直在重启,十分影响运行)

最后,也是问题得到了根本解决!!换了服务器,内存扩大了几倍,再也没出现过终止的情况,同时增加了 config/horizon 中 memory_limit 的限制 ,(所以 加钱才是王道(嗯,确信!),