Enrutamiento basado en contenido con RabbitMQ y Python

¿Es posible con RabbitMQ y Python hacer enrutamiento basado en contenido?

El estándar AMQP y RabbitMQ dicen ser compatibles con el enrutamiento basado en contenido, pero ¿hay alguna biblioteca para Python que admita la especificación de enlaces basados ​​en contenido, etc.?

La biblioteca que estoy usando actualmente (py-amqplib http://barryp.org/software/py-amqplib/ ) parece que solo admite el enrutamiento basado en temas con una simple coincidencia de patrones (#, *).

La respuesta es “sí”, pero hay más … 🙂

Primero acordemos qué significa enrutamiento basado en contenido. Hay dos significados posibles. Algunas personas dicen que se basa en la parte del encabezado de un mensaje. Otros dicen que se basa en la parte de datos de un mensaje.

Si tomamos la primera definición, estas son más o menos las suposiciones que hacemos: los datos surgen en algún lugar y se envían al agente AMQP por medio de algún software. Suponemos que esta pieza de software sabe lo suficiente sobre los datos para colocar pares clave-valor (KV) en el encabezado del mensaje que describe el contenido. Idealmente, el remitente también es el productor de los datos, por lo que tiene toda la información que podríamos desear. Digamos que los datos son una imagen. Entonces podríamos hacer que el remitente coloque pares KV en el encabezado del mensaje de esta manera:

width=1024 height=768 mode=bw photographer=John Doe 

Ahora podemos implementar el enrutamiento basado en contenido mediante la creación de colas apropiadas. Digamos que tenemos una operación separada para realizar en imágenes en blanco y negro y una separada en imágenes en color. Podemos crear dos colas, una que recibe mensajes con mode=bw y otra con mode=colour . Luego tenemos clientes separados escuchando en esas colas. El agente realiza el enrutamiento, y no hay nada en nuestro cliente que deba ser consciente del enrutamiento.

Si tomamos la segunda definición, partimos de diferentes suposiciones. Suponemos que los datos surgen en algún lugar, y se envían a un agente AMQP mediante un software. Pero suponemos que no es sensato exigir que ese software llene el encabezado con pares KV. En su lugar, queremos tomar una decisión de enrutamiento basada en los datos en sí.

Hay dos opciones para esto en AMQP: puede decidir implementar un nuevo intercambio para su formato de datos particular, o puede delegar el enrutamiento a un cliente.

En RabbitMQ, hay intercambios directos (1 a 1), fanout (1 a N), encabezados (encabezado filtrado 1 a N) y tema (tema filtrado a 1 a N), pero Puede implementar su propio acuerdo con el estándar AMQP. Esto requeriría leer mucha documentación de RabbitMQ e implementar el intercambio en Erlang.

La otra opción es hacer un cliente AMQP en Python que escuche una “cola de enrutamiento de contenido” especial. Cada vez que llega un mensaje a la cola, su enrutador-cliente lo recoge, hace lo que sea necesario para tomar una decisión de enrutamiento y envía el mensaje al agente a una cola adecuada. Entonces, para implementar el escenario anterior, su progtwig Python detectaría si una imagen está en blanco y negro o en color, y (re) la enviaría a una cola “en blanco y negro” o “a color”, donde algunos el cliente adecuado se haría cargo.

Entonces, en su segunda pregunta, realmente no hay nada que haga en su cliente que haga un enlace basado en contenido. O su cliente (s) funciona como se describe anteriormente, o crea un nuevo tipo de intercambio en el propio RabbitMQ. Luego, en el código de configuración de su cliente, usted define el tipo de intercambio como su nuevo tipo.

¡Espero que esto responda a su pregunta!

En RabbitMQ, el enrutamiento es el proceso mediante el cual un intercambio decide en qué colas colocar su mensaje. Publicas todos los mensajes en un intercambio, pero solo recibes mensajes de una cola. Esto significa que el intercambio es una parte activa del proceso que toma algunas decisiones sobre el reenvío o la copia de mensajes.

El intercambio de temas incluido con RabbitMQ mira una cadena en los mensajes entrantes (routing_key) y coincide con los patrones (binding_keys) suministrados por todas las colas que declaran su deseo de recibir mensajes del intercambio.

El código fuente de RabbitMQ está en la web, por lo que puede consultar el código de intercambio de temas aquí: http://hg.rabbitmq.com/rabbitmq-server/file/9b22dde04c9f/src/rabbit_exchange_type_topic.erl Hay mucha complejidad. para manejar una estructura de datos llamada trie que permite búsquedas muy rápidas. De hecho, la misma estructura de datos se utiliza dentro de los enrutadores de Internet.

El intercambio de encabezados que se encuentra aquí http://hg.rabbitmq.com/rabbitmq-server/file/9b22dde04c9f/src/rabbit_exchange_type_headers.erl es probablemente más fácil de entender. Como puede ver, no se requiere mucho código para realizar un tipo diferente de intercambio. Si quería examinar el contenido (o tal vez solo mirar los primeros bytes de mensajes, debería poder identificar rápidamente XML frente a JSON frente a otra cosa. Y si sus objetos JSON y documentos XML mantienen una secuencia específica de elementos, entonces debe poder distinguir entre diferentes objetos JSON (o tipos de documentos XML) sin analizar todo el cuerpo del mensaje.