php - para - capturando ProcessTimedOutException en la cola artesanal de Laravel: escuchar
aws/aws-sdk-php (7)
Tenemos un montón de trabajos de SQS que observamos y procesamos usando la php artisan queue:listen
de Laravel php artisan queue:listen
.
Periódicamente, tiene un par de minutos y SQS se agota. Cuando esto sucede, queue:listen
cancela con un mensaje como:
[Symfony/Component/Process/Exception/ProcessTimedOutException]
The process "php artisan queue:work
--queue="https://sqs.us-west-2.amazonaws.com/*******/queue"
--delay=0 --memory=128 --sleep=3 --tries=0 -env=production"
exceeded the timeout of 60 seconds.
He intentado manejar la excepción en app/start/global.php
y alternativamente app/start/artisan.php
:
App::error(function(Symfony/Component/Process/Exception/ProcessTimedOutException $exception) {
// do nothing
});
Desafortunadamente, la excepción sigue ocurriendo y mi queue:listen
sigue muriendo.
¿Cómo puedo detectar esta excepción e ignorarla para volver a intentarlo?
El problema parece estar relacionado con el tiempo de ejecución del trabajo en la cola, como sé, el tiempo de ejecución predeterminado de 30 segundos, debe aumentar este valor, puede aumentar de dos maneras,
php artisan queue:listen --timeout=1200
o puede establecer $timeout
de $timeout
para un trabajo específico
/**
* The number of seconds the job can run before timing out.
*
* @var int
*/
public $timeout = 1200;
Espero que esto sea de ayuda
Intente investigar los parámetros disponibles del comando ejecutando:
php artisan queue:listen --help
.
Puede pasar el valor de tiempo de espera en segundos, el número de intentos, etc.
Los tiempos de espera pasarán de vez en cuando. La clase de proceso de Symfony tiene su propia configuración de tiempo de espera que está causando este tiempo de espera en particular (creo). No estoy seguro de que pueda captar esto sin editar el código Laravel principal del trabajador, lo cual no es una buena idea.
Recomiendo encarecidamente usar el supervisor como se muestra en los documentos de Laravel:
https://laravel.com/docs/5.1/queues#supervisor-configuration
Esto reiniciará automáticamente su escucha incluso si falla.
No es una respuesta, sino más bien una solución:
Siempre que necesito asegurarme de que el proceso se ejecutará, incluso se produce un error, estoy usando npms para siempre . Esta práctica herramienta reiniciará el proceso tan pronto como se bloquee.
La instalación es bastante sencilla:
sudo apt-get install nodejs
sudo apt-get install npm
sudo ln -s /usr/bin/nodejs /usr/bin/node
sudo npm -g install forever
Use este comando para iniciar el proceso: forever start -c php artisan queue:listen
Si necesitas pararlo: forever stopall
Si ayuda, uso SupervisorD para ejecutar crons y tengo que disparar una cola: trabajar cada segundo, entonces no tengo ningún problema con SQS.
Usted ha vuelto a ejecutar el trabajo de cola "php artisan queue: work ..." en su controlador de excepciones,
o aumentar el valor de / vendor / symfony / process / Symfony / Component / Process / Process :: setTimeout () a algo superior.
O tal vez ambos.
<?php
namespace App;
use Illuminate/Bus/Queueable;
use Illuminate/Contracts/Queue/ShouldQueue;
use Illuminate/Foundation/Bus/Dispatchable;
use Illuminate/Queue/InteractsWithQueue;
use Illuminate/Queue/SerializesModels;
abstract class Job implements ShouldQueue, JobStatusInterface
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 1; // try only once
public function handle()
{
}
}
Use esta clase abstracta y envíela a la clase extendida para resolver su problema
<?php
namespace App;
use App/Job;
use Log;
use Exception;
/**
* Class CheckStockJob
*/
class CheckStockJob extends Job
{
public $tries = 100; // how many you need to retry
public function handle()
{
try {
// do something here
}
catch(Exception $e){
Log::error($e);
throw $e; // rethrow to make job fail
}
}
}
en algún lugar de tu código
$t = new CheckStockJob();
dispatch($t);