El RabbitMQ no obvio en Yii2 o por qué RabbitMQ escribe en todas las colas a la vez


Quiero compartir el problema práctico de configurar el intermediario de colas RabbitMQ en Yii2. Le advierto al lector que no tengo una opinión experta sobre cómo trabajar con este agente de colas, sin embargo, realmente quiero llenar los vacíos en la documentación de Yii2 y corregir el resultado de mi propio tormento. Entonces, si alguna vez ha encontrado un problema de que se están enviando mensajes a todas las colas que están en el servidor de colas, acepta que esto es un problema y no entiende por qué sucede esto, entonces le pido un gato.

¬ŅPor qu√© podr√≠as encontrar este comportamiento? Por ejemplo, si usted, como yo, no ha trabajado con RabbitMQ antes, pero trabaj√≥ por ejemplo con Gearman. Gearman en s√≠, tan simple como un ferrocarril ( tomado de un conocido y respetado personaje de Internet ). Crea una cola con un nombre determinado, coloca los datos all√≠. El trabajador lee de la cola con el mismo nombre. Todo es simple Ahora es el momento de usar la tecnolog√≠a de la moda, sin entender por qu√© eliges RabbitMQ. Entonces te alegra que Yii2 tenga una abstracci√≥n preparada para muchos corredores de colas populares. La escasa documentaci√≥n indica la configuraci√≥n predeterminada para que todo comience:

return [ 'bootstrap' => [ 'queue', // The component registers its own console commands ], 'components' => [ 'queue' => [ 'class' => \yii\queue\amqp_interop\Queue::class, 'port' => 5672, 'user' => 'guest', 'password' => 'guest', 'queueName' => 'queue', 'driver' => yii\queue\amqp_interop\Queue::ENQUEUE_AMQP_LIB, // or 'dsn' => 'amqp://guest:guest@localhost:5672/%2F', // or, same as above 'dsn' => 'amqp:', ], ], ]; 

Parece que todo es increíblemente simple, aquí está la línea familiar con queueName , copiar y pegar, arreglarlo, ejecutarlo, ¡funciona! Hacemos colas para otros componentes del sistema. Paralelamente con lo que nuestro php puede. Comprometerse, empujar satisfecho, ponemos la tarea en el control de calidad y vamos a leer un habr ( en el almuerzo ).

Aqu√≠, lo m√°s interesante, el control de calidad en el chat nos interrumpe y dice que algo extra√Īo est√° sucediendo. Por alguna raz√≥n, los datos que escriben los trabajadores (consumidores) est√°n duplicados. Que que No puede ser as√≠. Vamos a revisar los registros. Vemos que el mensaje se est√° escribiendo en la cola, con la cual la cola se selecciona correctamente, se recibe hash jobId. No, no, no tenemos errores. Estamos escribiendo QA satisfechos, verifique nuevamente, esto no puede ser, lo estamos haciendo bien.

Literalmente, después de media hora, nos distrajimos nuevamente, el error se repitió y luego cayó una notificación: la tarea fue transferida de regreso al trabajo. Bueno, soy programador, ahora lo resolveremos. RabbitMQ, a diferencia de Gearman, tiene una interfaz web en la que hay mucha información sobre el servidor. Este milagro se ve así:



Lanzamos un par de mensajes m√°s a la cola, vemos en el webmord que nuestros mensajes llegan y son procesados ‚Äč‚Äčpor el trabajador. Una mirada informal advierte que cuando lanzamos un mensaje a la cola, el cuadro de "Tasas de mensajes" salta en todas las colas.



Verificamos la configuración cien veces, volvemos a leer la escasa documentación de Yii. Hicimos todo bien. Vamos a leer la documentación en el sitio del conejo. Después de un par de decenas de minutos deambulando en la oscuridad, nos topamos con un tutorial . Inmediatamente después del primer párrafo, nos familiarizamos con la razón de nuestros malentendidos: intercambios. No repetiré la documentación, muy brevemente.

En RabbitMQ no escribimos un mensaje en la cola, lo escribimos para intercambiar, una especie de proxy que recibe nuestros mensajes en un extremo y se comunica con las colas en el servidor en el otro extremo. Est√° en su poder decidir en qu√© cola colocar nuestros datos. Curiosamente, no hay una sola l√≠nea sobre esto en la documentaci√≥n de Yii. A primera vista, no est√° claro c√≥mo configurar el intercambio, nos sumergimos en las entra√Īas y en el archivo vendor / yiisoft / yii2-queue / src / drivers / amqp_interop / Queue.php: 176 encontramos una propiedad apreciada que se puede poblar. Aqu√≠ debo decir que hay muchos controladores para RabbitMQ, en mi caso se usa enqueue / amqp-lib . Establecemos exchangeName , prueba, nada cambia. Bueno, somos como un verdadero ingeniero ruso, primero lo intentamos y luego volvemos a leer detenidamente la documentaci√≥n. Lo leemos cuidadosamente otra vez, luego vamos a la cara web de conejo y vemos lo siguiente:



Varias de nuestras colas están asociadas con el mismo intercambio. Bingo! Aquí está la razón, un "pero", no los até. Volvemos al intestino del controlador, encontramos la línea 392 del método setupBroker.

 $this->context->bind(new AmqpBind($queue, $topic)); 

Este es un enlace no administrado.

Y as√≠, sin pensarlo por mucho tiempo, llegamos a la conclusi√≥n de que para cada cola se debe declarar un intercambio, entonces la conexi√≥n ser√° correcta y un intercambio tendr√° solo una cola conectada. de esta manera obtenemos un comportamiento similar de Gearman. Por cierto, la documentaci√≥n describe en detalle por qu√© se realiz√≥ el intercambio, y seg√ļn tengo entendido, una de las razones es la capacidad de vincular varias colas con el intercambio. Pero no se me ocurri√≥ un caso como este cuando podr√≠a ser necesario, chicos escriben en los comentarios. Y escriba, ¬Ņha encontrado la situaci√≥n descrita anteriormente o estoy haciendo todo mal?

Source: https://habr.com/ru/post/439080/


All Articles