我在 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工匠队列:重新启动
清除了作业缓存版本的队列。问题是我对代码的更改从未运行,因此请确保运行此命令以确保作业队列使用最新的代码。
感谢输入!