Red de conocimiento informático - Aprendizaje de programación - ¿Cómo detecta laravel si la cola se está ejecutando?

¿Cómo detecta laravel si la cola se está ejecutando?

Servicio de cola

Los servicios relacionados con la cola de Laravel se encapsulan en servicios registrándose con el proveedor de servicios de cola del COI. El servicio de cola proporciona varios servicios para su función, consulte el siguiente código en los comentarios (el código es demasiado y no se ha publicado todo)

Registro de función pública ()

.

{

// Administrador de registro y administrador del servicio de cola unificado

$this->registerManager();

// Varios comandos para registrar la cola

$this->registerWorker();

$this->registerListener();

// Registra una tarea que no pudo ejecutar. p> // Registro cuando falla la ejecución de la tarea de registro

$this->registerFailedJobServices();

// Desconocido

$this->registerQueueClosure( );

}

Hablar archivo de configuración

Después de inyectar el servicio de cola en el COI, podemos usar la cola.

El trabajo más básico del servicio de cola es escribir tareas en la cola, luego sacarlas y ejecutarlas, lo cual es simple y claro. Por lo tanto, existen cuatro elementos básicos del servicio de cola: tarea, ingresar a la cola, sacarlo de la cola y ejecutar. Aquí seguiremos estos cuatro elementos y veremos cómo se implementan en laravel. Aquí, primero analizamos los ejemplos oficiales y luego aprendemos la esencia a través de ejemplos después de tener conceptos específicos.

Tarea

El servicio de cola está centrado en tareas. En el manual, a través de su ejemplo SendReminderEmail, podemos entender claramente que laravel puede hacer muchas cosas con las tareas, por ejemplo: puede establecer el número de reejecuciones, lo que indica que la tarea (si falla) se puede ejecutar varias veces. veces (para un solo Trabajo); puede establecer si es posible retrasar la ejecución del Trabajo; establecer el nombre de la cola para procesar tareas, etc. Estas funciones las proporciona \Illuminate\Bus\Queueable. Por supuesto, también hay un ejemplo de \Illuminate\Queue\InteractsWithQueue, que se utiliza para Job (más sobre esto más adelante). Después de crear una tarea, es necesario ponerla en una cola. Por supuesto, además de las características anteriores, también existe la lógica de ejecución de la tarea, etc. Para comprender completamente la tarea, necesita conocer su estructura de datos, y su estructura de datos se describirá en la cola en el cola.

La tarea ingresa a la cola

En el ejemplo, una vez definida la tarea, se utilizará el método Controlador para colocarla en la cola. Entonces, ¿cómo se implementa esto?

Código en :\Illuminate\Foundation\Bus\DispatchesJobs

función protegida despacho($job)

{

aplicación de devolución ( Dispatcher:. class)->dispatch($job);

}

/**

* Envía el comando al controlador correspondiente en el proceso actual. .

*

* @ param mixto $job

* @return mixto

*/

función pública Dispatcher::class)->.dispatchNow($job);

}

El propósito de este código debe ser comprender app(Dispatather::class), que es (por qué no se analiza aquí), app(), app(), app(), app(), app(), app( ) , app(), app() son claros. Dispather::clase) es (Illuminate\Bus\Dispatcher). Ahora, los métodos de envío y envío ahora en el código anterior se aclararán gradualmente. En resumen, la clase Dispatcher hace dos cosas: ejecutar tareas o poner tareas en la cola, es decir, las tareas de la cola se dividen en dos tipos: ejecución inmediata o ejecución de la cola de mensajes. El código relacionado con la cola es el siguiente:

/**

* Distribuir tareas a la cola

* @param string $ comando Clase de tarea

*/

función pública despachoToQueue($comando)

{

$conexión = isset($comando->conexión)?$comando->conexión: nulo;

// Laravel tiene una variedad de servicios de cola integrados, que se analizan aquí

$queue = call_user_func($this->queueResolver, $connection);

// El la cola está configurada para ser la misma que $comando->conexión Mismo valor.

// Si la resolución del servicio de cola no tiene éxito, lanza una excepción

if (! $queuestanceofQueue) {

throw new RuntimeException('Queue solucionador no devolvió una implementación de cola.');

}

// En la clase de tarea, puede personalizar el método de cola para ingresar a la cola

si ( método_existe($comando, 'cola')){

return $comando->cola($cola, $comando);

} else {

// Sistema Uno de los métodos para ingresar a la cola proporcionado por el sistema

return $this->pushCommandToQueue($queue, $command);

}

}

/*********** Seleccione el método de ingreso a la cola según los atributos de la tarea

* El método mencionado aquí no está disponible en el sistema, pero se puede hacer a través de múltiples formas de uso.

>* Los métodos mencionados aquí se mencionan en el manual

* @param Queue $queue servicio de cola

* @param $command clase de tarea

*/

función protegida pushCommandToQueue($queue, $command)

{

// Esta tarea push establece el retraso y establece el nombre de la cola

if (isset($comando->cola, $comando->retraso)) {

return $cola->laterOn ($comando->cola, $comando->retraso, $comando) ;

}

//Establece el nombre de la cola

if (isset($command-> queue)) {

return $queue-& gt;pushOn($command->queue, $command);

}

//establecer retraso

if (isset($command-> demora)) {

return $queue->later($command->delay, $command);

}

// predeterminado

return $queue-> push($command);

}

Hasta ahora, el El controlador ha demostrado un método para ingresar a la cola. Es obvio que es una interfaz proporcionada por el paquete. Aunque es muy útil, hay algunas operaciones que no necesitamos, como si ejecutar inmediatamente y diferentes parámetros de tarea. Es necesario configurarlo para ingresar a la cola. , esto requiere uno que sea más adecuado para nuestro uso, y si profundizamos un poco más, podemos encontrar los puntos clave por donde ingresa a la cola (y donde interactúa con Redis). Como se mencionó anteriormente, call_user_func($this->queueResolver,$connection obtendrá un servicio de cola, entonces, ¿qué es $this->queueResolver)? Puedes verlo en BusServiceProvider:23:

//¿Qué es esto->queueResolver?

// Para comprender esta devolución de llamada, debe comprender Illuminate/Contracts/Queue\Factory

// En proveedor/laravel/framework/src/Illuminate\Contracts\Queue\Factory

// En proveedor/laravel/framework/src/Illuminate\Contracts\Queue\Factory return call_user_func($this->connectors[$driver]);

}

throw new InvalidArgumentException("No hay conector para [$driver]");

}.

¿Por qué un código tan simple puede analizar el servicio de cola? Eche un vistazo a QueueServiceProvider y lo comprenderá. El proceso de procesamiento del servicio de cola de Redis es (Illuminate\Queue\RedisQueue.

La función de QueueManager ahora es muy clara.

1. Analizar el servicio de cola 2. Reenviar el procesamiento (__call) al servicio de cola correspondiente 3. Proporcionar interfaces relacionadas con la cola. Dado que QueueManager tiene tantas funciones relacionadas con la cola, podemos usarlo como entrada al procesamiento de la cola (acceder directamente al servicio de cola y luego realizar operaciones no es una buena elección. Casualmente, laravel hace lo mismo). Entonces ahora hay dos formas de ingresar a la cola: 1. Use \Illuminate\Foundation\Bus\DispatchesJobs para comunicarse con el servicio de cola indirectamente. 2. Use QueueManager para comunicarse con el servicio de cola indirectamente. Por supuesto, estos métodos se extienden en \Illuminate\Queue\RedisQueue (interfaz de servicio de cola). Entonces, al dominar esta clase, podrá comprender los diversos comportamientos de la cola.

RedisQueue

En lavavel se proporcionan varios servicios de cola. Aquí solo analizamos y estudiamos el servicio de cola de Redis. Por lo tanto, el procesamiento de colas se concentra en \Illuminate\Queue\RedisQueue. Como se mencionó anteriormente, hay dos formas de ingresar a la cola. Úselas por separado para ver cuáles son las diferencias en las estructuras de datos de las tareas que generan. (La estructura de datos es fácil de analizar, lo mencionaremos más adelante)

Utilice $this->dispatch((new SendReminderEmail()));

{

"trabajo":"Illuminate\\Queue\\\\ CallQueuedHandler@call",

"datos": {

"comando ":" O:26:\"Aplicación\\\Trabajos\\\EnviarReminderEmail\":4:{s:5:\"cola\";s:5:\"correo electrónico\";s:10 :\" conexión\" ;N;s:5:\"retraso \";N;s:6:\"\u0000*\u0000trabajo\";N;}"

},

" id":"7u00jImd8CAns0fQO8jedqkQmnbQsfsr",

" intentos": 1

}

Usando directamente Queue::push(SendReminderEmail::class , [ 'email' =>'123456789@qq.com'],'email');

{

"job"."App\\Jobs\\SendReminderEmail",

"data":{

"email":"123456789@qq.com"

},

"id":" I0OeBIQjJjisQrZ7STX3zexrBLF7Uilx ",

"attempts": 1

}

Como se mencionó anteriormente, se requieren dos procesos para formar una cola de mensajes, por lo que la entrada de la cola anterior es una proceso, y la salida de la cola y la ejecución de la tarea ahora se realiza en otro proceso. lavarel proporciona dos comandos para iniciar el proceso, quque:work y queue:litsen. Por supuesto, puede escribir comandos después de comprender cómo completar estas operaciones. Ahora veamos cómo se ejecutan las tareas y la eliminación de la cola.

Quitar tareas de la cola

En el manual, puede especificar varias propiedades para la tarea, como retraso, número de fallas, nombre de la cola, etc., por supuesto, todas las operaciones ejecutables o funciones Depende de la estructura de datos e implementa el comportamiento correspondiente formulando la estructura de datos. Por lo tanto, es más fácil comprender el código de RedisQueue utilizando la estructura de datos anterior.

RedisQueue es la interfaz básica de todos los servicios de cola (Redis), por lo que la operación de eliminar tareas de la cola también se puede encontrar aquí.

Suponiendo que ahora tenemos una cierta comprensión del código de RedisQueue, no es difícil encontrar que existe un método pop un poco más complicado (eliminar de cola). Entonces, aquí surge la pregunta: ¿cómo se implementa la eliminación de la cola? Una vez solucionado este problema, se completa la tarea de salir de la cola.

Función de la cola

Ver la cola php craft: work --help uso del comando, organizar las funciones o servicios requeridos relacionados con la cola:

Especificar la Nombre de la cola

Lógica de ejecución de tareas

Retraso en la ejecución de tareas

Número máximo de errores de tareas

Número máximo de errores de tareas

Por supuesto, también hay un número máximo de tareas fallidas

.

Por supuesto, el comando también tiene otras características, como: si se ejecuta como un proceso demonio, si se fuerza la ejecución, limita la memoria del proceso de ejecución y el tiempo de espera cuando no hay tareas. . Estas propiedades relacionadas con los comandos varían de un comando a otro y no tienen nada que ver con las tareas en cola. De esta forma, después de aclarar las funciones requeridas por la tarea de la cola, podemos analizar su estructura de datos y comprender el código.

Estructura de datos de la cola

La estructura de datos se basa en el comportamiento. Entonces, cuando analice el método pop, considere los siguientes puntos. En la estructura de datos anterior, ya puede ver la lógica de ejecución, los parámetros requeridos y la cantidad de fallas de la cola. Todos estos son obvios, por lo que no entraré en detalles. En todo el método pop, hay varias colas, a saber, Cola: Retraso, Cola: Reserva y Cola. Originalmente, sacar una tarea se puede completar con lpop. ¿Por qué necesitamos usar más de dos conjuntos (tenga en cuenta que los conjuntos ordenados no son colas) para completar la operación pop? Porque es necesario implementar el retraso de tareas y el manejo de fallas.

El proceso de implementación se muestra en la figura:

Análisis del proceso:

(1) Tome la tarea como ejemplo, porque la función de retraso es. Para lograrlo, hay La puntuación en la secuencia es el tiempo de vencimiento. El tiempo de vencimiento significa que no se ejecutará antes de este tiempo, lo que también logra el efecto de ejecución retrasada. El significado de retraso aquí no es cuántos segundos se ejecutará, sino cuántos segundos no se ejecutará. Para las tareas caducadas, se enviarán a la cola hasta que la operación lpop las elimine.

(1). ¿Por qué tener una cola: colección reservada y agregar tareas lpop a la rama? Porque siempre que la tarea se elimine, se puede registrar. Si el proceso finaliza de manera anormal antes de que se ejecute la tarea, la tarea no se perderá. Al ejecutarla nuevamente, puede eliminarla de acuerdo con los pasos anteriores para evitarlo. tarea se pierda accidentalmente.

(2). La ejecución de la cola se realiza en función del json de la clase. Esta parte es relativamente simple y se omitirá.

(3). Cuando la ejecución de la tarea sea exitosa, elimine manualmente la tarea en la cola: reservada; cuando la ejecución de la tarea falle, elimine la tarea en la cola: reservada y luego regístrela. cola zadd: retrasada y aumenta el número de ejecuciones de tareas en uno. Este proceso se ha encapsulado en RedisQueue (RedisQueue::release).

Esta serie de procesos completa la función de retrasar las tareas en cola. Entonces, todas estas complicaciones existen para implementar la funcionalidad de retraso, pero, por supuesto, también podría considerar implementarla usted mismo.

Ejecutar la tarea

En este punto, la ejecución de la tarea en la estructura de datos json es muy clara, y todo el proceso también es muy claro. Cabe señalar que la tarea debe eliminarse después de que se ejecute correctamente. Para saber cómo realizar la eliminación de la cola y cómo realizar tareas en la cola, puede ver el comando queue:work (\Illuminate\Queue\Console\WorkCommand::fire) en detalle, que es el mejor ejemplo

Queue; procesamiento Personalización de comandos

Al usar queue:work, descubrí que no puede manejar todas las situaciones. Por lo tanto, como se describe en este artículo, puede escribir sus propios comandos de procesamiento. Cuando encuentre un problema que queue:work no pueda resolver, puede considerar escribir sus propios comandos de procesamiento.

De hecho, hay muchos tipos de tareas y diferentes tareas deberían tener diferentes soluciones.

Por ejemplo:

Los errores causados ​​por el proveedor de servicios que ocurren al llamar al servicio deben registrarse por separado, pero dichos errores no se cuentan como errores de ejecución del trabajo.

Los mensajes de marketing solo se pueden enviar entre las 9:00 y las 20:00, por lo que no es necesario ejecutarlos durante este horario

Al interactuar con la base de datos, la conexión a la base de datos es la parte más importante el trabajo.

Al interactuar con la base de datos, la conexión a la base de datos tiene un límite de tiempo, pero no hay límite de tiempo cuando se ejecuta como proceso demonio, lo que dará lugar a errores

Por lo tanto, frente a la Limitaciones de los comandos proporcionados por la naturaleza de Laravel, es necesaria la capacidad de personalizar los comandos de procesamiento.