1

我在 Laravel 中遇到了一个我似乎无法解决的问题。作为我们应用程序的一部分,我们将大量作业添加到队列并使用queue:work执行它们。这是使用 Supervisor 设置的,并且运行良好。

我们在这个特定的命令上遇到了麻烦(其余的运行没有问题)。

在我们的应用程序中,我们使用调用自定义 shell 脚本命令

Symfony\组件\进程\进程;

但无论如何,我不断收到“进程超过 60 秒超时”错误。

错误: Symfony\Component\Process\Exception\ProcessTimedOutException:进程“'BIMTool.sh'”超过了 60 秒的超时。在 /var/www/app/vendor/symfony/process/Process.php:1263

BimTool.sh 脚本启动一系列涉及 Python 和 Anaconda3 的命令,以从 IFC 和点云生成 BIM 模型数据。我什至用“sleep 70”替换了 BimTool.sh 的内容,运行时仍然出现错误。

这是有问题的代码:

生成模型数据.php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Log;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
use Carbon\Carbon;

use App\Models\MongoDB\VisualizerModel;
use App\Models\PointCloud;
use App\Models\Project;

class GenerateModelData implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

protected $pointcloud;

/**
 * The number of times the job may be attempted.
 *
 * @var int
 */
public $tries = 3;

 /**
 * The number of seconds the job can run before timing out.
 *
 * @var int
 */
public $timeout = 1200;

/**
 * The number of seconds to wait before retrying the job.
 *
 * @var int
 */
public $backoff = 120;

/**
 * Create a new job instance.
 *
 * @return void
 */
public function __construct(PointCloud $pointcloud)
{
    $this->pointcloud = $pointcloud;
}

/**
 * Execute the job.
 *
 * @return void
 */
public function handle()
{
    // These commands can take +8 hours to execute in some cases
    ini_set('max_execution_time', 0);
    set_time_limit(0);

    $pointcloud = $this->pointcloud;

    $modelID = $pointcloud->models[0]->model_id;

    $model = VisualizerModel::find($modelID);

    $IFCFileName = substr($model->filename, 0, -5);

    $IFCFileLocation = "/var/www/app/storage/app/public/application/projects/{$model->project_uuid}/models/ifc/{$IFCFileName}.ifc";
    $PTSFileLocation = "/var/www/app/storage/app/public/{$pointcloud->storage_location}";
    $downSample = 15;
    $uuid = $model->project_uuid;
    $date = Carbon::parse($pointcloud->scan_date)->format('d/m/Y');
    $modelDataID = $model->model_data_id;

    $process = new Process(['BIMTool.sh',
        $IFCFileLocation,
        $PTSFileLocation,
        $downSample,
        $uuid,
        $modelID,
        $date,
        $modelDataID 
    ]);

    $process->setTimeout(1200);
    $process->setIdleTimeout(1200);
    $process->start();

    // Executes after the command finishes
    if (!$process->isSuccessful()) {

        throw new ProcessFailedException($process);

    } else {
        // Command was succesfull

        // Some code here

    }
}

/**
 * Catch error if job fails.
 *
 * @return \Symfony\Component\Process\Exception\ProcessFailedException
 */
public function failed(ProcessFailedException $exception)
{
   return $exception;
}

我当然已经在 Stackoverflow(以及互联网上)搜索过这个问题,并尝试了我遇到的所有解决方案,但没有任何效果。

到目前为止我所尝试的(但没有一个有效)

  • 将 php.ini 中的 max_input_time 设置更改为 0、-1 和 1200
  • 将 php.ini 中的 max_execution_time 设置更改为 0、-1 和 1200
  • $process->setTimeout(1200);
  • $process->setIdleTimeout(1200);
  • ini_set('max_execution_time', 0);
  • 设置时间限制(0);
  • 在 Supervisor 命令中添加了 --timeout=0

环境配置

Linode 运行 Ubuntu 18.04.5 LTS
LAMP-stack
Anaconda3
Laravel 5.8

主管配置

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/app/artisan queue:work database --sleep=5 --tries=3 --timeout=0 -- 
queue=default
autostart=true
autorestart=true
user=bc
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/app/worker.log

什么可能导致进程超过了 60 秒的超时错误?无论我尝试什么,我都会得到它。

编辑:(这为我解决了)

所以事实证明队列也有一个“缓存”。运行命令:

php工匠队列:重新启动

清除了作业缓存版本的队列。问题是我对代码的更改从未运行,因此请确保运行此命令以确保作业队列使用最新的代码。

感谢输入!

4

0 回答 0