web-dev-qa-db-fra.com

RabbitMQ et relation entre canal et connexion

Le client RabbitMQ Java présente les concepts suivants:

  • Connection - une connexion à une instance de serveur RabbitMQ
  • Channel - ???
  • Pool de threads consommateurs - un pool de threads qui consomment des messages hors des files d'attente du serveur RabbitMQ
  • File d'attente - une structure qui contient les messages dans l'ordre FIFO

J'essaie de comprendre la relation, et plus important encore , les associations entre eux.

  1. Je ne suis toujours pas sûr de ce qu'est une Channel, mis à part le fait qu'il s'agit de la structure à partir de laquelle vous publiez et que vous utilisez, et qu'elle est créée à partir d'une connexion ouverte. Si quelqu'un pouvait m'expliquer ce que représente le "canal", cela pourrait aider à clarifier certaines choses.
  2. Quelle est la relation entre Channel et Queue? Le même canal peut-il être utilisé pour communiquer avec plusieurs files d'attente ou doit-il être 1: 1?
  3. Quelle est la relation entre la file d'attente et le pool de consommateurs? Plusieurs consommateurs peuvent-ils être abonnés à la même file d'attente? Plusieurs files d'attente peuvent-elles être consommées par le même consommateur? Ou est la relation 1: 1?

Merci d'avance pour toute aide ici!

153
user1768830
  1. Un Connection représente une réelle connexion TCP au courtier de messages, alors qu'un Channel est une connexion virtuelle (connexion AMPQ) à l'intérieur. De cette façon, vous pouvez utiliser autant de connexions (virtuelles) que vous le souhaitez dans votre application sans surcharger le courtier avec TCP connexions.

  2. Vous pouvez utiliser un Channel pour tout. Cependant, si vous avez plusieurs threads, il est suggéré d'utiliser un Channel différent pour chaque thread.

    Chaîne thread-safety dans Java Guide de l'API client :

    Les instances de canal peuvent être utilisées par plusieurs threads en toute sécurité. Les demandes dans un canal sont sérialisées, un seul thread pouvant exécuter une commande sur le canal à la fois. Même dans ce cas, les applications doivent préférer utiliser un canal par thread au lieu de partager le même canal sur plusieurs threads.

    Il n'y a pas de relation directe entre Channel et Queue. Un Channel est utilisé pour envoyer des commandes AMQP au courtier. Cela peut être la création d'une file d'attente ou similaire, mais ces concepts ne sont pas liés.

  3. Chaque Consumer s'exécute dans son propre thread alloué à partir du pool de threads grand public. Si plusieurs consommateurs sont abonnés à la même file d'attente, le courtier utilise la méthode alternée pour répartir les messages de manière égale. Voir Didacticiel deux: "Files d'attente" .

    Il est également possible d'associer le même Consumer à plusieurs files d'attente. Vous pouvez comprendre les consommateurs comme des rappels. Celles-ci sont appelées à chaque fois qu'un message arrive dans une file d'attente à laquelle le consommateur est lié. Dans le cas du client Java, chaque consommateur dispose d'une méthode handleDelivery(...), qui représente la méthode de rappel. Ce que vous faites généralement est la sous-classe DefaultConsumer et le remplacement de handleDelivery(...). Remarque: Si vous associez la même instance de consommateur à plusieurs files d'attente, cette méthode sera appelée par différents threads. Donc, prenez soin de la synchronisation si nécessaire.

173
Bengt

Une bonne compréhension conceptuelle de ce que le protocole AMQP fait "sous le capot" est utile ici. Je proposerais que la documentation et l'API qu'AMQP 0.9.1 a choisi de déployer rend cette situation particulièrement déroutante. La question elle-même est donc une question à laquelle de nombreuses personnes doivent faire face.

TL; DR

Un connexion est le socket physique négocié TCP avec le serveur AMQP. Les clients correctement implémentés auront un de ceux-ci par application, thread-safe, partageable entre les threads.

Un canal est une session d'application unique sur la connexion. Un fil aura une ou plusieurs de ces sessions. L’architecture AMQP 0.9.1 stipule que ceux-ci ne doivent pas être partagés entre les threads et doivent être fermés/détruits lorsque le thread qui l’a créé est terminé. Ils sont également fermés par le serveur lorsque diverses violations de protocole se produisent.

Un consommateur est une construction virtuelle qui représente la présence d'une "boîte aux lettres" sur un canal particulier. L'utilisation d'un consommateur indique au courtier d'envoyer les messages d'une file d'attente particulière au point de terminaison de ce canal.

Faits de connexion

Tout d’abord, comme d’autres l'ont bien fait remarquer, une connexion est l'objet qui représente la connexion réelle TCP au serveur. Les connexions sont spécifiées au niveau du protocole dans AMQP et toutes les communications avec le courtier s'effectuent via une ou plusieurs connexions.

  • Puisqu'il s'agit d'une connexion TCP réelle, elle possède une adresse IP et un numéro de port.
  • Les paramètres de protocole sont négociés sur une base client par client dans le cadre de la configuration de la connexion (un processus connu sous le nom de poignée de main.
  • Il est conçu pour être longue vie; il y a peu de cas où la fermeture de connexion fait partie de la conception du protocole.
  • Du point de vue de l'OSI, il réside probablement quelque part autour de couche 6
  • Les pulsations peuvent être configurées pour surveiller l’état de la connexion, car TCP ne contient rien en soi.
  • Il est préférable qu'un thread dédié gère les lectures et les écritures sur le socket TCP sous-jacent. La plupart des clients RabbitMQ, sinon tous, le font. À cet égard, ils sont généralement thread-safe.
  • Relativement parlant, les connexions sont "chères" à créer (à cause de la poignée de main), mais dans la pratique, cela n'a pas d'importance. La plupart des processus n'auront réellement besoin que d'un seul objet de connexion. Cependant, vous pouvez maintenir les connexions dans un pool si vous constatez que vous avez besoin de plus de débit qu'un thread/socket unique peut fournir (peu probable avec la technologie informatique actuelle).

Faits concernant la chaîne

Un canal est la session de l'application ouverte pour que chaque élément de votre application puisse communiquer avec le courtier RabbitMQ. Il fonctionne sur un seul connexion et représente une session avec le courtier.

  • Comme il représente une partie logique de la logique d'application, chaque canal existe généralement sur son propre thread.
  • En règle générale, tous les canaux ouverts par votre application partagent une seule connexion (il s'agit de sessions légères qui fonctionnent au-dessus de la connexion). Les connexions sont thread-safe, donc c'est OK.
  • La plupart des opérations AMQP ont lieu sur des canaux.
  • Du point de vue de la couche OSI, les canaux sont probablement autour de couche 7 .
  • Les canaux sont conçus pour être transitoires ; Une partie de la conception de AMQP est que le canal est généralement fermé en réponse à une erreur (par exemple, redéclarer une file d'attente avec des paramètres différents avant de supprimer la file d'attente existante).
  • Comme ils sont transitoires, les canaux ne doivent pas être regroupés par votre application.
  • Le serveur utilise un entier pour identifier un canal. Lorsque le thread qui gère la connexion reçoit un paquet pour un canal particulier, il utilise ce numéro pour indiquer au courtier à quel canal/session appartient le paquet.
  • Les canaux ne sont généralement pas sécurisés pour les threads, car cela n'aurait aucun sens de les partager entre les threads. Si vous avez un autre thread qui doit utiliser le courtier, un nouveau canal est nécessaire.

Renseignements sur le consommateur

Un consommateur est un objet défini par le protocole AMQP. Ce n'est ni un canal, ni une connexion, mais plutôt quelque chose que votre application utilise comme "boîte aux lettres" pour supprimer des messages.

  • "Création d'un consommateur" signifie que vous indiquez au courtier (à l'aide d'un canal via une connexion) que vous souhaitez que les messages vous soient transmis via ce canal. En réponse, le courtier enregistrera que vous avez un consommateur sur le canal et commence à vous envoyer des messages.
  • Chaque message envoyé sur la connexion référencera à la fois un numéro de canal et un numéro de consommateur. De cette manière, le thread de gestion de connexion (dans ce cas, au sein de l'API Java>) sait quoi faire avec le message; alors, le thread de traitement de canal sait également quoi faire avec le message.
  • L'implémentation grand public présente la plus grande variation, car elle est littéralement spécifique à une application. Dans mon implémentation, j'ai choisi de créer une tâche à chaque fois qu'un message arrivait via le consommateur; ainsi, j'avais un fil gérant la connexion, un fil gérant le canal (et par extension le consommateur) et un ou plusieurs fils de tâche pour chaque message transmis via le consommateur.
  • La fermeture d'une connexion ferme tous les canaux de la connexion. La fermeture d'un canal ferme tous les consommateurs du canal. Il est également possible de annuler un consommateur (sans fermer le canal). Il y a divers cas où il est logique de faire l'une des trois choses.
  • En règle générale, la mise en œuvre d'un consommateur dans un client AMQP allouera un canal dédié au consommateur pour éviter les conflits avec les activités d'autres threads ou codes (y compris la publication).

En ce qui concerne ce que vous entendez par pool de threads de consommation, je soupçonne que Java client effectue quelque chose de similaire à ce que j'ai programmé pour mon client (le mien était basé sur le client .Net, mais fortement modifié).

41
theMayer

J'ai trouvé cet article qui explique tous les aspects du modèle AMQP, dont canal est l'un. J'ai trouvé cela très utile pour compléter ma compréhension

https://www.rabbitmq.com/tutorials/amqp-concepts.html

Certaines applications nécessitent plusieurs connexions à un courtier AMQP. Cependant, il n'est pas souhaitable de garder plusieurs connexions TCP ouvertes en même temps, car cela consomme des ressources système et complique la configuration du pare-feu. Les connexions AMQP 0-9-1 sont multiplexées avec des canaux que l'on peut qualifier de "connexions légères partageant une seule connexion TCP connexion".

Pour les applications qui utilisent plusieurs threads/processus pour le traitement, il est très courant d'ouvrir un nouveau canal par thread/processus et de ne pas partager les canaux entre eux.

La communication sur un canal particulier est complètement séparée de la communication sur un autre canal. Par conséquent, chaque méthode AMQP porte également un numéro de canal que les clients utilisent pour déterminer le canal auquel la méthode est destinée (et par conséquent, le gestionnaire d'événement devant être appelé, par exemple). .

19
CamW