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é).