Routage basé sur le contenu avec RabbitMQ et Python

est-il possible avec RabbitMQ et Python de faire du routage basé sur le contenu?

la norme AMQP et RabbitMQ prétendent prendre en charge le routage basé sur le contenu, mais y a-t-il des bibliothèques pour Python qui prennent en charge la spécification de reliures basées sur le contenu, etc.?

la bibliothèque que j'utilise actuellement (py-amqplib http://barryp.org/software/py-amqplib / ) semble ne prendre en charge que le routage par sujet avec simple correspondance de pattern ( # ,*).

7
demandé sur safl 2010-07-19 15:37:51

2 réponses

la réponse est" oui", mais il y a plus... :)

commençons par nous mettre d'accord sur ce que signifie le routage basé sur le contenu. Il y a deux sens possibles. Certaines personnes disent qu'il est basé sur la partie en-tête d'un message. D'autres disent que c'est basé sur la partie data d'un message.

si nous prenons la première définition, ce sont plus ou moins les hypothèses que nous faisons: Les données vient à l'existence quelque part, et il est envoyé au courtier AMQP par un logiciel. Nous supposons que ce logiciel en sait assez sur les données pour mettre des paires de valeurs clés (KV) dans le en-tête du message qui décrit le contenu. Idéalement, l'expéditeur est aussi le producteur des données, donc il a autant d'informations que nous pourrions jamais vouloir. Disons que les données sont une image. Nous pourrions alors demander à l'expéditeur de mettre des paires KV dans l'en-tête du message comme ceci:

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

maintenant nous pouvons implémenter le routage basé sur le contenu en créant des files d'attente appropriées. Disons que nous avons une opération distincte à effectuer sur les images en noir et blanc et une autre sur les images en couleur. Nous pouvons créer deux files d'attente, l'une qui reçoit des messages avec mode=bw et l'autre avec mode=colour . Ensuite, nous avons des clients séparés qui écoutent ces Files d'attente. Le courtier effectue le routage, et il n'y a rien dans notre client qui doit être au courant du routage.

si nous prenons la deuxième définition, nous allons partir d'hypothèses différentes. Nous supposons que les données existent quelque part, et qu'elles sont envoyées à un courtier AMQP par un logiciel quelconque. Mais nous supposons qu'il n'est pas raisonnable d'exiger que ce logiciel remplisse l'en-tête de paires KV. Au lieu de cela, nous voulons prendre une décision de routage basée sur les données elle-même.

il y a deux options pour cela dans AMQP: vous pouvez décider d'implémenter un nouvel échange pour votre format de données particulier, ou vous pouvez déléguer le routage à un client.

dans RabbitMQ, il y a des échanges directs (1-to-1), fanout (1-to-N), headers (header-filtered 1-to-N) et topic (topic-filtered 1-to-N), mais vous pouvez implémenter votre propre standard selon AMQP. Pour ce faire, il faudrait lire beaucoup de documentation sur RabbitMQ et mettre en œuvre L'échange dans Erlang.

l'autre option est de faire un client AMQP en Python qui écoute spécial "le contenu de routage de la file d'attente". Chaque fois qu'un message arrive dans la file d'attente, votre routeur client récupère, tout ce qui est nécessaire pour prendre une décision de routage, et envoie le message au courtier à une file d'attente. Ainsi, pour mettre en œuvre le scénario ci-dessus, votre programme Python détecterait si une image est en noir et blanc ou en couleur, et l'enverrait (re)à une file d'attente "en noir et blanc" ou "en couleur", où un client approprié prendrait la relève.

donc sur votre deuxième question, il n'y a vraiment rien que vous faites dans votre client qui fait une reliure basée sur le contenu. Soit votre(Vos) client (s) fonctionne (NT) comme décrit ci-dessus, soit vous créez un nouveau type d'échange dans RabbitMQ lui-même. Ensuite, dans le code de configuration de votre client, vous définissez le type d'échange comme étant votre nouveau type.

espérons que cela réponde à votre question!

16
répondu Fabian Fagerholm 2010-08-11 12:41:13

Dans RabbitMQ, le routage est le processus par lequel un échange décide de files d'attente pour passer votre message. Vous publiez tous les messages à un échange, mais vous ne recevez les messages que d'une file d'attente. Cela signifie que l'échange est une partie active du processus qui prend certaines décisions concernant le transfert ou la copie de messages.

l'échange de thème inclus avec RabbitMQ regarde une chaîne sur les messages entrants (la routing_key) et correspond avec les modèles (le binding_keys) fournis par toutes les files d'attente qui déclarent leur désir de recevoir des messages de l'échange.

RabbitMQ code source est sur le web afin que vous puissiez jeter un oeil au sujet code d'échange ici: http://hg.rabbitmq.com/rabbitmq-server/file/9b22dde04c9f/src/rabbit_exchange_type_topic.erl Une grande partie de la complexité est de gérer une structure de données appelée un trie qui permet des recherches très rapides. En fait, la même structure de données est utilisée à l'intérieur Les routeurs de l'Internet.

Les en-têtes de change trouvé ici http://hg.rabbitmq.com/rabbitmq-server/file/9b22dde04c9f/src/rabbit_exchange_type_headers.erl est probablement plus facile à comprendre. Comme vous pouvez le voir il n'y a pas beaucoup de code nécessaires pour faire un autre type d'échange. Si vous souhaitez examiner le contenu (ou peut-être juste jeter un coup d'oeil aux premiers octets des messages, vous devriez être en mesure d'identifier rapidement XML par rapport à JSON par rapport à autre chose. Et si vos objets JSON et documents XML maintiennent une séquence spécifique d'éléments alors vous devriez être en mesure de faire la distinction entre les différents objets JSON (ou types de documents XML) sans analyser le corps de message entier.

5
répondu Michael Dillon 2011-06-01 04:17:58