Uma boa compreensão conceitual do que o protocolo AMQP faz "sob o capô" é útil aqui. Eu diria que a documentação e a API que o AMQP 0.9.1 optou por implantar tornam isso particularmente confuso, de modo que a questão em si é aquela que muitas pessoas precisam enfrentar.
TL; DR
Uma conexão é o soquete TCP negociado físico com o servidor AMQP. Os clientes implementados adequadamente terão um desses por aplicativo, thread-safe, compartilhável entre threads.
Um canal é uma única sessão de aplicativo na conexão. Um encadeamento terá uma ou mais dessas sessões. A arquitetura AMQP 0.9.1 é que eles não devem ser compartilhados entre os threads e devem ser fechados / destruídos quando o thread que o criou terminar com ele. Eles também são fechados pelo servidor quando ocorrem várias violações de protocolo.
Um consumidor é uma construção virtual que representa a presença de uma "caixa de correio" em um canal específico. O uso de um consumidor informa ao broker para enviar mensagens de uma fila específica para o nó de extremidade do canal.
Fatos da conexão
Primeiro, como outros apontaram corretamente, uma conexão é o objeto que representa a conexão TCP real com o servidor. As conexões são especificadas no nível do protocolo no AMQP, e toda a comunicação com o broker ocorre através de uma ou mais conexões.
- Por ser uma conexão TCP real, ela possui um endereço IP e um número de porta.
- Os parâmetros do protocolo são negociados por cliente como parte da configuração da conexão (um processo conhecido como handshake) .
- Ele foi projetado para durar muito ; Existem poucos casos em que o fechamento da conexão faz parte do design do protocolo.
- De uma perspectiva OSI, provavelmente reside em algum lugar da Camada 6
- Os batimentos cardíacos podem ser configurados para monitorar o status da conexão, pois o TCP não contém nada por si só para fazer isso.
- É melhor ter um thread dedicado para gerenciar leituras e gravações no soquete TCP subjacente. A maioria, se não todos, os clientes RabbitMQ fazem isso. Nesse sentido, eles geralmente são seguros para threads.
- Relativamente falando, as conexões são "caras" para criar (devido ao aperto de mão), mas na prática, isso realmente não importa. A maioria dos processos realmente precisará apenas de um objeto de conexão. Porém, você pode manter conexões em um pool, se achar que precisa de mais taxa de transferência do que um único encadeamento / soquete pode fornecer (improvável com a tecnologia de computação atual).
Fatos do canal
Um canal é a sessão do aplicativo que é aberta para cada parte do seu aplicativo se comunicar com o broker RabbitMQ. Ele opera em uma única conexão e representa uma sessão com o broker.
- Como representa uma parte lógica da lógica do aplicativo, cada canal geralmente existe em seu próprio encadeamento.
- Normalmente, todos os canais abertos pelo seu aplicativo compartilham uma única conexão (são sessões leves que operam na parte superior da conexão). As conexões são seguras para threads, então isso é bom.
- A maioria das operações da AMQP ocorre por canais.
- De uma perspectiva da camada OSI, os canais provavelmente estão em torno da camada 7 .
- Os canais são projetados para serem transitórios ; parte do design do AMQP é que o canal normalmente é fechado em resposta a um erro (por exemplo, declarar novamente uma fila com parâmetros diferentes antes de excluir a fila existente).
- Como são transitórios, os canais não devem ser agrupados pelo seu aplicativo.
- O servidor usa um número inteiro para identificar um canal. Quando o encadeamento que gerencia a conexão recebe um pacote para um canal específico, ele usa esse número para informar ao broker a que canal / sessão o pacote pertence.
- Os canais geralmente não são seguros para threads, pois não faria sentido compartilhá-los entre os threads. Se você tiver outro encadeamento que precise usar o broker, será necessário um novo canal.
Fatos do Consumidor
Um consumidor é um objeto definido pelo protocolo AMQP. Não é um canal nem uma conexão, sendo algo que seu aplicativo específico usa como uma "caixa de correio" para eliminar mensagens.
- "Criando um consumidor" significa que você diz ao broker (usando um canal por meio de uma conexão ) que gostaria que as mensagens fossem enviadas a você por esse canal. Em resposta, o broker registrará que você tem um consumidor no canal e começará a enviar mensagens para você.
- Cada mensagem enviada pela conexão fará referência a um número de canal e um número de consumidor . Dessa forma, o encadeamento de gerenciamento de conexões (nesse caso, dentro da API Java) sabe o que fazer com a mensagem; então, o segmento de manipulação de canal também sabe o que fazer com a mensagem.
- A implementação do consumidor tem a maior variação possível, porque é literalmente específica do aplicativo. Na minha implementação, optei por executar uma tarefa cada vez que uma mensagem chegava através do consumidor; portanto, eu tinha um encadeamento gerenciando a conexão, um encadeamento gerenciando o canal (e, por extensão, o consumidor) e um ou mais encadeamentos de tarefas para cada mensagem entregue pelo consumidor.
- Fechar uma conexão fecha todos os canais na conexão. Fechar um canal fecha todos os consumidores no canal. Também é possível cancelar um consumidor (sem fechar o canal). Existem vários casos em que faz sentido executar qualquer uma das três coisas.
- Normalmente, a implementação de um consumidor em um cliente AMQP alocará um canal dedicado ao consumidor para evitar conflitos com as atividades de outros threads ou códigos (incluindo publicação).
Em termos do que você quer dizer com pool de encadeamentos do consumidor, suspeito que o cliente Java esteja fazendo algo semelhante ao que eu programei (o meu foi baseado no cliente .Net, mas fortemente modificado).