감독자를 사용하여 대기열에 있는 작업을 모니터링하세요.
으아악사용
으아악실패한 큐 기록은 확립되었으나, 실패한 큐는 항상 반복적으로 실행되어 failed_job에 기록되지 않는 상황입니다
laravel 문서에서
으아악연결 이름은 무엇을 의미하나요?
php artisan queue:listen --timeout=0 --tries=3, 큐 실행 오류
으아악이러한 문제를 해결하는 방법은 무엇입니까?
高洛峰2017-05-16 16:58:46
laravel에서는 다양한 큐 서비스를 선택할 수 있는데, 대표적인 것이 redis와 beanstalk입니다. redis는 단순한 db이기 때문에 데이터가 완전히 투명하므로 여기서는 redis를 설명 객체로 사용하면 이해가 더 쉬울 것입니다. .
laravel의 대기열 시작 메소드에는 queue:listen
및 queue:work
가 포함됩니다. 여기서 queue:work
는 다음 작업을 별도로 실행한다는 의미입니다. 차이점 참고: queue:listen과 queue:work --daemon의 차이점을 참조하세요. queue:listen
은 queue:work
를 계속해서 호출하여 내부적으로 구현됩니다. 이제 work
명령을 살펴보겠습니다. queue:listen
和queue:work
, 其中queue:work
表示单独运行下一个job. 关于区别请看:queue:listen 和 queue:work --daemon 的区别 。queue:listen
内部也是一次次的调用queue:work
实现的,现在我们来看work
命令。
在IlluminateQueueConsoleWorkCommand
中是不是看见了我们熟悉的fire
方法?对就是它。继续追,
调用runWork
方式查找job并且执行.这里有一个daemon
选项, 表示是否作为守护运行。直接将daemon认为false(因为daemon其实就是一个while(true) ):joy:。
看到runWork
其实是调用的IlluminateQueueWorker::pop
方法
public function pop($connectionName, $queue = null, $delay = 0, $sleep = 3, $maxTries = 0)
{
$connection = $this->manager->connection($connectionName); //这里就是你说的连接名称,实际就是选择一个合理的queue服务,只要你没有用某个队列服务的特有的方法,那么各个队列可以随时切换使用的.
$job = $this->getNextJob($connection, $queue); //查找一个job对象
// If we're able to pull a job off of the stack, we will process it and
// then immediately return back out. If there is no job on the queue
// we will "sleep" the worker for the specified number of seconds.
if ( ! is_null($job))
{
//如果job存在则执行任务
return $this->process(
$this->manager->getName($connectionName), $job, $maxTries, $delay
);
}
$this->sleep($sleep);
return ['job' => null, 'failed' => false];
}
到了最终执行job的位置(删掉了空行和注释,因为我要来上蹩脚的中文注释了.(逃 ):
public function process($connection, Job $job, $maxTries = 0, $delay = 0)
{
if ($maxTries > 0 && $job->attempts() > $maxTries){ //看见了吗,运行的时候先查看了job的执行次数如果超过了最大次数,则直接进入logFailedJob过程,也就是将失败的job存储到指定的数据库中, 观察`Illuminate\Queue\Jobs\RedisJob`中的`attempts `方法和`release`方法。一个查看attempts次数,一个增加attempts次数(当然release还有其他操作).那么找找谁调用了release方法(看下面的trycatch,就是在出现异常之后并且job没有被删除的情况下会调用release)?如果没有抛出异常?那么attempts是不会变化的。
return $this->logFailedJob($connection, $job);
}
try{
$job->fire();// job的fire方法实际已经将我们指定的JobClass用Container::make并且执行了fire方法.
if ($job->autoDelete()) $job->delete();
return ['job' => $job, 'failed' => false];
} catch (\Exception $e){
if ( ! $job->isDeleted()) $job->release($delay);
throw $e;
}
}
恩,差不多就是这么回事了。
你那个抛出来的Swift_TransportException
是发送邮件程序swiftmailer
IlluminateQueueConsoleWorkCommand
에서 익숙한 fire
메서드를 보셨나요? 그게 다야. 계속 쫓아오세요.runWork
메서드를 호출하여 작업을 찾아 실행합니다. 여기에는 데몬으로 실행할지 여부를 나타내는 daemon
옵션이 있습니다. 데몬을 false로 직접 고려하십시오(데몬은 실제로 while(true)이기 때문에):joy:. 🎜
🎜runWork
가 실제로 IlluminateQueueWorker::pop
메서드를 호출하는지 확인하세요🎜
으아악
🎜작업의 최종 실행 위치에 도착했습니다. (엉터리 중국어 댓글을 쓸 예정이라 빈 줄과 댓글을 삭제했습니다. (탈출):🎜
으아악
🎜글쎄요, 거의 다 됐어요. 🎜
🎜당신이 던진 Swift_TransportException
은 이메일 전송 프로그램 swiftmailer
에서 발생한 오류입니다🎜