211 votes

RabbitMQ et la relation entre canal et connexion

Le site Client Java RabbitMQ comporte les concepts suivants :

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

J'essaie de comprendre la relation, et surtout le associations entre eux.

  1. Je ne suis toujours pas sûr de ce qu'est un Channel est, autre que le fait que c'est la structure à partir de laquelle vous publiez et consommez, et qu'elle est créée à partir d'une connexion ouverte. Si quelqu'un pouvait m'expliquer ce que représente le "Channel", cela pourrait aider à clarifier certaines choses.
  2. Quelle est la relation entre le canal et la file d'attente ? 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 s'agit-il d'une relation 1:1 ?

234voto

Bengt Points 2592
  1. A Connection représente une connexion TCP réelle au courtier en messages, tandis qu'une connexion de type Channel est une connexion virtuelle (connexion AMQP) à l'intérieur de celle-ci. De cette façon, vous pouvez utiliser autant de connexions (virtuelles) que vous le souhaitez dans votre application sans surcharger le courtier avec des connexions TCP.

  2. Vous pouvez utiliser un Channel pour tout. Cependant, si vous avez plusieurs fils de discussion, il est conseillé d'utiliser un autre fichier Channel pour chaque fil.

    Sécurité des fils du canal dans le guide API du client Java :

    Les instances de canaux sont sûres pour une utilisation par plusieurs threads. Les requêtes dans un canal sont sérialisées, et un seul thread peut exécuter une commande sur le commande sur le canal à la fois. Malgré cela, les applications devraient préférer préférer l'utilisation d'un canal par thread plutôt que le partage du même canal entre plusieurs plusieurs threads.

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

  3. Chaque Consumer s'exécute dans son propre thread alloué à partir du pool de threads du consommateur. Si plusieurs consommateurs sont abonnés à la même file d'attente, le courtier utilise la méthode round-robin pour distribuer les messages entre eux de manière égale. Voir Didacticiel n°2 : "Les files d'attente". .

    Il est également possible d'attacher le même Consumer à plusieurs files d'attente. Vous pouvez comprendre les Consumers comme des callbacks. Ils sont appelés chaque fois qu'un message arrive sur 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, c'est de sous-classer DefaultConsumer et de passer outre handleDelivery(...) . Note : Si vous attachez la même instance de Consumer à plusieurs files d'attente, cette méthode sera appelée par différents threads. Prenez donc soin de la synchronisation si nécessaire.

70voto

rmayer06 Points 2447

Une bonne compréhension conceptuelle de ce que le protocole AMQP fait "sous le capot" est utile ici. Je dirais que la documentation et l'API qu'AMQP 0.9.1 a choisi de déployer rendent la situation particulièrement confuse, de sorte que la question elle-même est une question avec laquelle de nombreuses personnes doivent se débattre.

TL;DR

A connexion est le socket TCP physique négocié avec le serveur AMQP. Les clients correctement implémentés auront un de ces sockets par application, sans risque pour les threads, partageable entre les threads.

A canal est une session d'application unique sur la connexion. Un thread aura une ou plusieurs de ces sessions. Selon l'architecture AMQP 0.9.1, ces sessions ne doivent pas être partagées entre les threads et doivent être fermées/détruites lorsque le thread qui les a créées en a fini avec elles. Elles sont également fermées par le serveur lorsque diverses violations du protocole se produisent.

A 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 de pousser les messages d'une file d'attente particulière vers le point de terminaison de ce canal.

Faits concernant la connexion

Premièrement, comme d'autres l'ont souligné à juste titre, une connexion est l'objet qui représente la connexion TCP réelle au serveur. Les connexions sont spécifiées au niveau du protocole dans AMQP, et toute communication avec le courtier se fait par une ou plusieurs connexions.

  • Comme il s'agit d'une véritable connexion TCP, elle possède une adresse IP et un numéro de port.
  • Les paramètres du protocole sont négociés pour chaque client dans le cadre de l'établissement de la connexion (un processus connu sous le nom d'échange de données). poignée de main .
  • Il est conçu pour être à long terme ; il existe peu de cas où la fermeture de la connexion fait partie de la conception du protocole.
  • D'un point de vue OSI, il se situe probablement quelque part autour de Couche 6
  • Des battements de cœur peuvent être mis en place pour surveiller l'état de la connexion, car le protocole TCP ne contient rien en soi pour ce faire.
  • 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 "coûteuses" à créer (en raison de la poignée de main), mais en pratique, cela n'a pas vraiment d'importance. La plupart des processus n'ont besoin que d'un seul objet de connexion. Mais, vous pouvez maintenir des connexions dans un pool, si vous trouvez que vous avez besoin de plus de débit qu'un seul thread/socket peut fournir (peu probable avec la technologie informatique actuelle).

Faits sur la chaîne

A Chaîne est la session d'application qui est ouverte pour chaque élément de votre application afin de communiquer avec le courtier RabbitMQ. Elle fonctionne sur un seul connexion et représente un session avec le courtier.

  • Comme il représente une partie logique de la logique applicative, chaque canal existe généralement sur son propre thread.
  • En général, 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 à l'abri des threads, donc c'est correct.
  • La plupart des opérations AMQP se déroulent sur des canaux.
  • D'un point de vue de la couche OSI, les canaux sont probablement environ Couche 7 .
  • Les canaux sont conçus pour être transitoires ; une partie de la conception d'AMQP est que le canal est typiquement 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 existante).
  • Comme ils sont transitoires, les canaux ne doivent pas être mis en commun par votre application.
  • Le serveur utilise un nombre entier pour identifier un canal. Lorsque le thread qui gère la connexion reçoit un paquet pour un canal particulier, il utilise ce nombre pour indiquer au broker à quel canal/session le paquet appartient.
  • Les canaux ne sont généralement pas sécurisés par les threads, car il serait insensé de les partager entre les threads. Si un autre thread doit utiliser le broker, un nouveau canal est nécessaire.

Faits concernant les consommateurs

Un consommateur est un objet défini par le protocole AMQP. Il ne s'agit ni d'un canal ni d'une connexion, mais plutôt d'un objet que votre application particulière utilise comme une sorte de "boîte aux lettres" pour déposer des messages.

  • " Créer un consommateur " signifie que vous indiquez au courtier (à l'aide d'une canal via un connexion ) que vous souhaitez que les messages vous soient transmis sur ce canal. En réponse, le courtier enregistrera que vous disposez d'un canal consommateur sur le canal et commencer à vous envoyer des messages.
  • Chaque message poussé sur la connexion référencera à la fois un numéro de canal et un numéro du consommateur . De cette manière, le thread de gestion des connexions (dans ce cas, au sein de l'API Java) sait ce qu'il doit faire du message ; ensuite, le thread de gestion des canaux sait également ce qu'il doit faire du message.
  • La mise en œuvre du consommateur est la plus variable, car elle est littéralement spécifique à l'application. Dans mon implémentation, j'ai choisi de lancer une tâche à chaque fois qu'un message arrivait via le consommateur ; ainsi, j'avais un thread gérant la connexion, un thread gérant le canal (et par extension, le consommateur), et un ou plusieurs threads de tâche pour chaque message délivré via le consommateur.
  • Fermeture d'un connexion ferme tous les canaux sur la connexion. La fermeture d'un canal ferme tous les consommateurs sur le canal. Il est également possible de annuler un consommateur (sans fermer le canal). Il existe plusieurs cas où il est judicieux de faire l'une de ces trois choses.
  • En général, l'implémentation d'un consommateur dans un client AMQP alloue un canal dédié au consommateur pour éviter les conflits avec les activités d'autres threads ou codes (y compris la publication).

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

25voto

CamW Points 1693

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

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

Certaines applications ont besoin de connexions multiples à un courtier AMQP. Cependant, il n'est pas souhaitable de garder de nombreuses connexions TCP ouvertes en même temps car cela consomme des ressources système et rend plus difficile la configuration des pare-feu. Les connexions AMQP 0-9-1 sont multiplexées avec des canaux qui peuvent être considérés comme des "connexions légères qui partagent une seule connexion TCP".

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, c'est pourquoi chaque méthode AMQP porte également un numéro de canal que les clients utilisent pour savoir à quel canal la méthode est destinée (et donc, quel gestionnaire d'événement doit être invoqué, par exemple).

10voto

AtulJain Points 138

Il y a une relation entre le genre Une connexion TCP peut avoir plusieurs canaux. .

Chaîne : C'est une connexion virtuelle à l'intérieur d'une connexion. Lorsque vous publiez ou consommez des messages à partir d'une file d'attente, tout se fait par le biais d'un canal. Connexion : Il s'agit d'une connexion TCP entre votre application et le broker RabbitMQ.

Dans une architecture multithreading, vous pouvez avoir besoin d'une connexion séparée par thread. Cela peut conduire à une sous-utilisation de la connexion TCP, mais aussi à une surcharge pour le système d'exploitation qui doit établir autant de connexions TCP que nécessaire pendant les périodes de pointe du réseau. Les performances du système pourraient être considérablement réduites. C'est là que le canal est utile, il crée des connexions virtuelles à l'intérieur d'une connexion TCP. Il réduit immédiatement l'overhead du système d'exploitation et nous permet d'effectuer des opérations asynchrones de manière plus rapide, plus fiable et plus simultanée. enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X