Una buona comprensione concettuale di ciò che il protocollo AMQP fa "sotto il cofano" è utile qui. Vorrei offrire che la documentazione e l'API che AMQP 0.9.1 ha scelto di distribuire rendono questo aspetto particolarmente confuso, quindi la domanda stessa è quella con cui molte persone devono confrontarsi.
TL; DR
Una connessione è il socket TCP negoziato fisico con il server AMQP. I client correttamente implementati ne avranno uno per applicazione, thread-safe, condivisibile tra i thread.
Un canale è una singola sessione dell'applicazione sulla connessione. Una discussione avrà una o più di queste sessioni. L'architettura AMQP 0.9.1 è che questi non devono essere condivisi tra i thread e devono essere chiusi / distrutti al termine del thread che l'ha creato. Inoltre, vengono chiusi dal server quando si verificano varie violazioni del protocollo.
Un consumatore è un costrutto virtuale che rappresenta la presenza di una "cassetta postale" su un determinato canale. L'uso di un consumatore indica al broker di inviare i messaggi da una determinata coda all'endpoint del canale.
Fatti di connessione
Innanzitutto, come altri hanno correttamente sottolineato, una connessione è l'oggetto che rappresenta la connessione TCP effettiva al server. Le connessioni sono specificate a livello di protocollo in AMQP e tutte le comunicazioni con il broker avvengono su una o più connessioni.
- Poiché è una connessione TCP effettiva, ha un indirizzo IP e un numero di porta.
- I parametri del protocollo vengono negoziati su una base per client come parte della configurazione della connessione (un processo noto come stretta di mano .
- È progettato per essere longevo ; ci sono alcuni casi in cui la chiusura della connessione fa parte del progetto del protocollo.
- Dal punto di vista OSI, risiede probabilmente da qualche parte attorno al Livello 6
- Gli heartbeat possono essere impostati per monitorare lo stato della connessione, poiché TCP non contiene nulla in sé e per sé.
- È preferibile che un thread dedicato gestisca le letture e le scritture nel socket TCP sottostante. La maggior parte, se non tutti, i clienti RabbitMQ lo fanno. A tale proposito, sono generalmente sicuri per i thread.
- Relativamente parlando, le connessioni sono "costose" da creare (a causa della stretta di mano), ma praticamente parlando, questo non importa. La maggior parte dei processi avrà davvero bisogno di un solo oggetto di connessione. Tuttavia, è possibile mantenere le connessioni in un pool, se si ritiene che sia necessario un throughput maggiore di quello che può fornire un singolo thread / socket (improbabile con l'attuale tecnologia di elaborazione).
Fatti del canale
Un canale è la sessione dell'applicazione che viene aperta per ogni parte dell'app per comunicare con il broker RabbitMQ. Funziona su una singola connessione e rappresenta una sessione con il broker.
- Poiché rappresenta una parte logica della logica dell'applicazione, ogni canale di solito esiste sul proprio thread.
- In genere, tutti i canali aperti dalla tua app condivideranno una singola connessione (sono sessioni leggere che operano in cima alla connessione). Le connessioni sono thread-safe, quindi va bene.
- La maggior parte delle operazioni AMQP avviene tramite canali.
- Dal punto di vista del livello OSI, i canali sono probabilmente attorno al livello 7 .
- I canali sono progettati per essere transitori ; parte della progettazione di AMQP è che il canale è in genere chiuso in risposta a un errore (ad es. dichiarare nuovamente una coda con parametri diversi prima di eliminare la coda esistente).
- Poiché sono transitori, i canali non devono essere raggruppati dalla tua app.
- Il server utilizza un numero intero per identificare un canale. Quando il thread che gestisce la connessione riceve un pacchetto per un determinato canale, utilizza questo numero per indicare al broker a quale canale / sessione appartiene il pacchetto.
- I canali non sono generalmente sicuri per i thread in quanto non avrebbe senso condividerli tra i thread. Se si dispone di un altro thread che deve utilizzare il broker, è necessario un nuovo canale.
Fatti di consumo
Un consumatore è un oggetto definito dal protocollo AMQP. Non è né un canale né una connessione, ma è qualcosa che la tua particolare applicazione utilizza come una "cassetta postale" per eliminare i messaggi.
- "Creazione di un consumatore" significa che dici al broker (usando un canale tramite una connessione ) che desideri che i messaggi ti vengano inviati su quel canale. In risposta, il broker registrerà che hai un consumatore sul canale e inizierà a inviarti messaggi.
- Ogni messaggio inviato sulla connessione farà riferimento sia a un numero di canale che a un numero utente . In questo modo, il thread di gestione della connessione (in questo caso, all'interno dell'API Java) sa cosa fare del messaggio; quindi, il thread di gestione dei canali sa anche cosa fare con il messaggio.
- L'implementazione del consumatore ha la più ampia gamma di variazioni, perché è letteralmente specifica per l'applicazione. Nella mia implementazione, ho scelto di escludere un'attività ogni volta che un messaggio arrivava tramite il consumatore; quindi, avevo un thread che gestiva la connessione, un thread che gestiva il canale (e per estensione, il consumatore) e uno o più thread di attività per ciascun messaggio recapitato tramite il consumatore.
- La chiusura di una connessione chiude tutti i canali sulla connessione. La chiusura di un canale chiude tutti i consumatori sul canale. È anche possibile cancellare un consumatore (senza chiudere il canale). Ci sono vari casi in cui ha senso fare una delle tre cose.
- In genere, l'implementazione di un consumatore in un client AMQP alloca un canale dedicato al consumatore per evitare conflitti con le attività di altri thread o codice (inclusa la pubblicazione).
In termini di cosa intendi per pool di thread dei consumatori, sospetto che il client Java stia facendo qualcosa di simile a quello che ho programmato per il mio client (il mio era basato sul client .Net, ma fortemente modificato).