Laravel Event事件异步错漏,失败的异常队列不会进入failed_job
基于Laravel Event=> Listener机制 编写的异步代码
在本地环境,Listener都正常执行,但是生产环境时而执行时而被跳过,也不报错,有人知道这是什么原因么。
介于服务器环境的问题,我自己编写了Event模块(代码如下),其机制是,Event在内部的 public function handle 中执行 Listenter的代码,如果Listener是异步,则将Event自身放入队列,并最终在队列中异步执行Listener。
但问题也来了,如果Listener抛出异常,能看到队列报错,但队列不会进入failed_job表,这使得重要的业务将被漏过。(具体请看代码注释)
这该怎么处理?求助,或者告诉我手动将队列放入failed_job表的方法。
<?php
namespace App\Events;
use App\Providers\EventServiceProvider as Service;
use Illuminate\Contracts\Queue\ShouldQueue as Queue;
abstract class SD implements Queue
{
use \Illuminate\Bus\Queueable;
use \Illuminate\Queue\SerializesModels;
use \Illuminate\Queue\InteractsWithQueue;
use \Illuminate\Foundation\Bus\Dispatchable;
public $tries = 2;
protected $listener;
final public function handle ()
{
# 异步队列执行监听任务
if ($this->listener) {
// 此处抛出异常,队列将报错并进入failed_job
// throw new \Exception('666');
// 如果Listener代码跑出异常,队列报错,但是不进入failed_job,而且在试过其他处理方式后,我发现只要在整个应用中抛出一次异常,那么再手动抛出异常,队列也不会进入failed_job
return (new $this->listener)->handle($this);
}
# 事件传递至监听任务
if ($listener = Service::listener(static::class) ) {
$job = [];
foreach ($listener as &$cls) {
$cls = new $cls;
if ($cls instanceof Queue) {
$obj = $this->copy();
$obj->listener = get_class($cls);
$obj->queue = @$cls->queue ?: 'default';
$obj->connection = @$cls->connection ?: 'redis';
$obj->delay = @$cls->delay ?: ($this->delay ?: 0);
$obj->tries = (int)@$cls->tries>1 ? (int)@$cls->tries : 2;
$job[] = $obj;
} else {
$cls->handle($this);
}
}
$job && dispatchArray($job);
}
}
abstract protected function copy () :self;
}
想问下楼主怎么解决的,我也遇到了这个问题