search

Home  >  Q&A  >  body text

Laravel 4 queue uses beanstalkd, how to record to failed_job table when failed

Use supervisor to monitor the jobs in the queue,

php artisan queue:listen --timeout=0

use

php artisan queue:failed-table

Failed queue records have been established, but the current situation is that failed ones are always executed repeatedly and are not written to failed_job

There is

in laravel documentation
php artisan queue:listen connection-name --tries=3

What does connection-name refer to?

php artisan queue:listen --timeout=0 --tries=3, queue execution error

exception 'Swift_TransportException' with message 'Expected response code 250 but got code "", with message ""'

How to solve these problems?

滿天的星座滿天的星座2738 days ago765

reply all(2)I'll reply

  • 高洛峰

    高洛峰2017-05-16 16:58:46

    You can choose from a variety of queue services in laravel, the common ones are redis and beanstalk. Since redis is a simple db, the data is completely transparent, so it will be easier to understand if redis is used as the explanation object here.

    The way to start the queue in laravel is the queue:listenqueue:work, 其中queue:work表示单独运行下一个job. 关于区别请看:queue:listen 和 queue:work --daemon 的区别 。queue:listen内部也是一次次的调用queue:work实现的,现在我们来看workcommand.

    In IlluminateQueueConsoleWorkCommand中是不是看见了我们熟悉的firemethod? That's it. Keep chasing,
    Call the runWork方式查找job并且执行.这里有一个daemon option to indicate whether to run as a daemon. Directly consider daemon as false (because daemon is actually a while(true)):joy:.

    See runWork其实是调用的IlluminateQueueWorker::popmethod

    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];
    }
    

    Arrived at the final execution position of the job (deleted the blank lines and comments, because I am going to write crappy Chinese comments. (Escape):

    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;
        }
    }
    

    Well, that’s pretty much it.

    The Swift_TransportException是发送邮件程序swiftmailererror you threw

    reply
    0
  • phpcn_u1582

    phpcn_u15822017-05-16 16:58:46

    In the connections configuration in config/queue.php, sync, beanstalkd, sqs, etc. are the connection-name.

    reply
    0
  • Cancelreply