Une bonne compréhension conceptuelle de ce que fait le protocole AMQP «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 cela particulièrement déroutant, donc la question elle-même est une question avec laquelle beaucoup de gens doivent se débattre.
TL; DR
Une connexion est le socket TCP physique négocié avec le serveur AMQP. Les clients correctement implémentés en auront un 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 est 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éé en a 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 de pousser les messages d'une file d'attente particulière vers ce point de terminaison de canal.
Faits de connexion
Tout d'abord, 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 toutes les communications avec le courtier se font via une ou plusieurs connexions.
- Puisqu'il s'agit d'une connexion TCP réelle, elle a une adresse IP et un numéro de port.
- Les paramètres de protocole sont négociés sur une base par client dans le cadre de la configuration de la connexion (un processus connu sous le nom de handshake .
- Il est conçu pour durer longtemps ; il existe peu de cas où la fermeture de la connexion fait partie de la conception du protocole.
- Du point de vue OSI, il réside probablement quelque part autour de la couche 6
- Les pulsations peuvent être configurées pour surveiller l'état de la connexion, car TCP ne contient rien en lui-même 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 "chères" à 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'auront vraiment besoin que d'un seul objet de connexion. Mais, vous pouvez maintenir les connexions dans un pool, si vous trouvez que vous avez besoin de plus de débit qu'un seul thread / socket ne peut en fournir (peu probable avec la technologie informatique actuelle).
Informations sur la chaîne
Un canal est la session d'application qui est ouverte pour chaque élément de votre application pour communiquer avec le courtier RabbitMQ. Il fonctionne sur une seule 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 partageront une seule connexion (ce sont des 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 la couche 7 .
- Les canaux sont conçus pour être transitoires ; Une partie de la conception d'AMQP est que le canal est généralement fermé en réponse à une erreur (par exemple, re-dé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 gérant la connexion reçoit un paquet pour un canal particulier, il utilise ce numéro pour indiquer au courtier à quel canal / session le paquet appartient.
- Les canaux ne sont généralement pas sûrs pour les threads car il 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.
Faits sur les consommateurs
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 particulière utilise comme une sorte de «boîte aux lettres» pour déposer des messages.
- "Créer un consommateur" signifie que vous dites au courtier (en utilisant un canal via une connexion ) que vous souhaitez que les messages vous soient envoyés via ce canal. En réponse, le courtier enregistrera que vous avez un consommateur sur le canal et commencera à vous envoyer des messages.
- Chaque message poussé sur la connexion référencera à la fois un numéro de canal et un numéro de consommateur . De cette façon, le thread de gestion de connexion (dans ce cas, dans l'API Java) sait quoi faire avec le message; ensuite, le thread de gestion des canaux 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 à l'application. Dans ma mise en œuvre, j'ai choisi de spin off 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âches pour chaque message délivré via le consommateur.
- La fermeture d'une connexion ferme tous les canaux de la connexion. La fermeture d'un canal ferme tous les consommateurs sur le canal. Il est également possible d' annuler un consommateur (sans fermer le canal). Il existe divers cas où il est logique de faire l'une des trois choses.
- En règle générale, l'implémentation 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 code (y compris la publication).
En ce qui concerne ce que vous entendez par pool de threads grand public, je soupçonne que le client Java fait quelque chose de similaire à ce que j'ai programmé pour mon client (le mien était basé sur le client .Net, mais fortement modifié).