多个队列侦听器将在多个进程上运行相同的作业

时间:2014-11-10 01:06:30

标签: php laravel beanstalkd

我有一个用Laravel 4.2框架编写的简单Web应用程序。我已配置Laravel队列组件以将新队列项添加到本地运行的beastalkd服务器。

基本上,有一个POST路由会将一个项目添加到beanstalkd管。

然后我将supervisord设置为运行artisan queue:listen作为三个单独的进程。我看到的问题是,不同的queue:listen进程最终会在一到三个queue:worker进程中产生,只有一个插入的作业。

最终结果是插入队列的一个作业有时会被多个工作人员同时处理,这显然是我试图避免的。

工作代码相对简单:

<?php

use App\Repositories\URLRepository;

class ProcessDataJob {
    private $urls;

    public function __construct(URLRepository $urls)
    {
        $this->urls = $urls;
    }

    public function fire($job, $data)
    {
        $input = $data['post'];

        if (!isset($data['post']) && !is_array($data['post'])) {
            Log::error('[Job #'.$job->getJobId().'] $input was empty inside CreateAuditJob. Deleting job. Quitting. Bye!');
            $job->delete();
            return false;
        }

        //
        // ... code that will take a few hours to run.
        //

        $job->delete();
        Log::info('[Job #'.$job->getJobId().'] ProcessDataJob was successful, deleting the job!');
        return true;
    }
}

有趣的是,大多数(重复的)队列工作程序在删除错误日志中留下的作业时失败了:

exception 'Pheanstalk_Exception_ServerException' with message 'Job 3248 NOT_FOUND: does not exist or is not reserved by client'

ttr(运行时间)设置为172,800秒(或48小时),这比作业完成所需的时间要大得多。

1 个答案:

答案 0 :(得分:3)

排队时的工作时间_to_run是什么?如果运行作业的时间超过time_to_run秒,则作业将自动重新排队,并有资格由下一个工作人员运行。

保留作业的time_to_run秒数将被删除,释放或触摸。调用touch()会重新启动超时计时器,因此工作人员可以使用它来为自己提供更多时间来完成。或者在排队时使用足够大的值。

我发现beanstalkd协议文档很有帮助 https://github.com/kr/beanstalkd/blob/master/doc/protocol.md