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