如何在 Laravel 4.2 中编写多进程队列(配置了 supervisord)?

How to write multiprocess queues in Laravel 4.2 (having supervisord configured)?

我有一个网站,用户可以在其中导出 CSV 格式的报告。当他们单击 "Export" 按钮时,我在数据库中添加了一个新行 table,表示有一个新的报告生成请求。

我想为 2 个进程设置数据库访问权限,因为 1 个进程不够。我当前的 supervisord 配置如下:

    [program:csv_export]
    command=php /var/www/mywebsite.com/artisan queue:listen --tries=1 --timeout=3000 --queue=csv_export
    numprocs=2
    process_name=csv_export_%(process_num)02d
    directory=/var/www/mywebsite.com/
    stdout_logfile=/var/log/mywebsite/csv_export.log
    autostart=true
    autorestart=true
    stopsignal=KILL
    loglevel=debug
    redirect_stderr=true

我的队列 fire() 代码如下所示:

public function fire($job, $data){
    $reports = \CSVReport::where('status', '=', CSVReport::CSVNEW)->take(1)->get();

    foreach ($reports as $key => $value){
        // prepare data and file
        $value->status = 'done';
        $value->save();
    }

    $job->delete();
}

我正在使用 Laravel 4.2,尚无法升级。我想避免两个进程访问数据库中相同的 table 行的情况。我怎样才能避免在我的队列中出现这种情况 class?

假设您将作业推送到队列中,例如:

$csv = new CSVReport;
// $csv->... = ...;
$csv->save();
Queue::push('ExportCSV', array('csvID' => $csv->id));

Job fire 方法使用 $data 参数传递特定值以确保 Job 执行特定操作。现在在 ExportCSV 作业中,在 fire 方法中:

public function fire($job, $data){
    $report = \CSVReport::find($data['csvID']);

    // prepare data and file
    $report->status = 'done';
    $report->save();

    $job->delete();
}

这样每个 Job 都会在他的 $data 中序列化 CSVReport ID,当 supervisord 执行它时,Job 只会处理他在数据库中的特定 CVSReport ID。

如果可以在队列外处理它们,您仍然可以检查状态是否已完成:

public function fire($job, $data){
    $report = \CSVReport::where('status', CSVReport::CSVNEW)->where('id', $data['csvID'])->first();

    // prepare data and file
    if($report) {
        $report->status = 'done';
        $report->save();
    }

    $job->delete();
}