{"id":73065,"date":"2020-03-06T20:42:13","date_gmt":"2020-03-06T17:42:13","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings"},"modified":"2020-03-06T20:42:13","modified_gmt":"2020-03-06T17:42:13","slug":"rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings","status":"publish","type":"post","link":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings","title":{"rendered":"RabbitMQ. Parte 3. Approfondiamo Queues e Bindings","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><code>Coda<\/code> (coda) \u2014 struttura dati su disco o in memoria che conserva riferimenti ai messaggi e restituisce copie di essi <code>consumatori<\/code> (ai consumatori). <code>Coda<\/code> \u00e8 rappresentato da <noindex><a rel=\"nofollow\" href=\"http:\/\/erlang.org\/doc\/reference_manual\/processes.html\">un processo Erlang<\/a><\/noindex> con stato (dove possono essere memorizzati anche i messaggi). 1.000 code possono occupare circa 80Mb.<\/p>\n<p><\/p>\n<p><code>Binding<\/code> (legame) \u2014 \u00e8 una regola che informa l'exchange a quale coda devono arrivare i messaggi.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3 id=\"oglavlenie\">Indice<\/h3>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/488654\/\">RabbitMQ. Parte 1. Introduzione. Erlang, AMQP e RPC<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/489086\/\">RabbitMQ. Parte 2. Approfondiamo gli Exchanges<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/490960\/\">RabbitMQ. Parte 3. Approfondiamo Queues e Bindings<\/a><\/noindex><\/li>\n<li>RabbitMQ. Parte 4. Analizziamo cosa sono i messaggi e i frame<\/li>\n<li>RabbitMQ. Parte 5. Performance di pubblicazione e consumo dei messaggi<\/li>\n<li>RabbitMQ. Parte 6. Panoramica sui moduli Federation e Shovel<\/li>\n<li>RabbitMQ. Parte 7. Dettagli su Connection e Channel<\/li>\n<li>RabbitMQ. Parte 8. RabbitMQ in .NET<\/li>\n<li>RabbitMQ. Parte 9. Monitoraggio<\/li>\n<\/ul>\n<p><\/p>\n<h4 id=\"vremennye-ocheredi\"><em>Code temporanee<\/em><\/h4>\n<p><\/p>\n<p>Se la creazione di una coda avviene con il parametro impostato <code>autoDelete<\/code>, allora tale coda acquisisce la capacit\u00e0 <strong>di eliminarsi automaticamente<\/strong>. Tali code vengono solitamente create al momento della connessione del primo client e rimosse quando tutti i client si disconnettono. <\/p>\n<p><\/p>\n<p>Se la creazione di una coda avviene con il parametro impostato <code>esclusiva<\/code>, allora tale coda <strong>consente di collegare solo un utente<\/strong> e viene rimossa se il canale si chiude. Finch\u00e9 il canale rimane attivo, il cliente pu\u00f2 disconnettersi\/ricollegarsi, ma solo all'interno della stessa connessione. Se il parametro <code>esclusiva<\/code> \u00e8 impostato, il parametro <code>autoDelete<\/code> non ha alcun effetto.<\/p>\n<p><\/p>\n<p>Caratteristiche:<\/p>\n<p><\/p>\n<ul>\n<li>In caso di breve interruzione della connessione, perderemo i messaggi che non sono ancora stati consegnati all'utente<\/li>\n<li>si pu\u00f2 osservare il fenomeno <code>binding churn<\/code>. Il fenomeno si verifica quando il numero di operazioni di creazione\/rimozione di code e collegamenti raggiunge valori molto elevati. In modalit\u00e0 cluster, questo flusso di operazioni si diffonder\u00e0 su tutti i nodi, creando un alto carico. Questo processo pu\u00f2 essere ottimizzato controllando il numero di sottoscrizioni.<\/li>\n<\/ul>\n<p><\/p>\n<h4 id=\"postoyannye-ocheredi\"><em>Code persistenti<\/em><\/h4>\n<p><\/p>\n<p>Se la creazione di una coda avviene con il parametro impostato <code>durable<\/code>, allora tale coda <strong>mantiene il proprio stato<\/strong> e si ripristina dopo il riavvio del server\/broker. Questa coda esister\u00e0 finch\u00e9 non verr\u00e0 invocato il comando <code>Queue.Delete<\/code>. <\/p>\n<p><\/p>\n<h4 id=\"highly-available-ocheredi\"><em>Code ad alta disponibilit\u00e0<\/em><\/h4>\n<p><\/p>\n<p>Le code HA richiedono un ambiente cluster RabbitMQ. In modalit\u00e0 cluster, tutte le informazioni su exchange, code, collegamenti e consumatori saranno replicate su tutti i nodi.<\/p>\n<p><\/p>\n<p>Quando un messaggio viene pubblicato in una coda HA, viene memorizzato su ciascun nodo associato a quella coda HA. Dopo che il messaggio \u00e8 stato consumato su uno dei nodi, tutte le copie di quel messaggio verranno eliminate sugli altri nodi. <\/p>\n<p><\/p>\n<p>Le code HA possono estendersi a tutti i nodi in un certo cluster o solo a nodi specifici. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Parte 3. Approfondiamo Queues e Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/46d560ab33e686ddf9adb0b18b4bb0b0.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Caratteristiche:<\/p>\n<p><\/p>\n<ul>\n<li>l'uso delle code HA comporta un impatto sulle prestazioni. Quando un messaggio viene inserito in una coda HA o consumato da essa, RabbitMQ deve coordinare l'operazione su tutti i nodi (2-3 nodi sono generalmente sufficienti).<\/li>\n<\/ul>\n<p><\/p>\n<h4 id=\"sozdanie-ocheredi\"><em>Creazione della coda<\/em><\/h4>\n<p><\/p>\n<p>La creazione della coda avviene tramite una <code>richiesta RPC<\/code> al server. La richiesta viene effettuata utilizzando il metodo <code>Queue.Declare<\/code>, chiamato con i seguenti parametri:<\/p>\n<p><\/p>\n<ul>\n<li>nome della coda<\/li>\n<li>altri parametri<\/li>\n<\/ul>\n<p><\/p>\n<p>Esempio di creazione di una coda utilizzando <noindex><a rel=\"nofollow\" href=\"https:\/\/www.rabbitmq.com\/dotnet.html\">RabbitMQ.Client<\/a><\/noindex>:<\/p>\n<p><\/p>\n<pre><code class=\"cs\">\/\/ ...\nchannel.QueueDeclare(\n    queue: &quot;my_queue&quot;,\n    durable: false,\n    exclusive: false,\n    autoDelete: false,\n    arguments: null\n);\n\/\/ ...<\/code><\/pre>\n<p><\/p>\n<ul>\n<li><code>queue<\/code> \u2014 \u00e8 il nome della coda che desideriamo creare. Il nome deve essere unico e non pu\u00f2 coincidere con il nome di sistema della coda.<\/li>\n<li><code>durable<\/code> \u2014 se true, la coda sar\u00e0 <strong>in grado di mantenere il proprio stato<\/strong> e verr\u00e0 ripristinata dopo il riavvio del server\/broker.<\/li>\n<li><code>esclusiva<\/code> \u2014 se true, la coda permetter\u00e0 di connettersi solo a un consumatore<\/li>\n<li><code>autoDelete<\/code> \u2014 se true, la coda acquisisce la capacit\u00e0 <strong>di eliminarsi automaticamente<\/strong><\/li>\n<li><code>argomenti<\/code> \u2014 argomenti opzionali. Approfondiamo di seguito.<\/li>\n<\/ul>\n<p><\/p>\n<h5 id=\"arguments\"><em>argomenti<\/em><\/h5>\n<p><\/p>\n<ul>\n<li><code>x-message-ttl<\/code>(<code>x-message-time-to-live<\/code>) \u2014 consente di impostare il tempo di scadenza del messaggio in millisecondi. Se la coda viene creata con un valore impostato per l'argomento <code>x-message-ttl<\/code>, tale coda <strong>escluder\u00e0 automaticamente i messaggi scaduti<\/strong>. Impostare il valore dell'argomento <code>x-message-ttl<\/code> definisce l'et\u00e0 massima per tutti i messaggi in questa coda. Creare tale coda <strong>permette di evitare di ricevere informazioni obsolete<\/strong>. Questo pu\u00f2 essere utilizzato in sistemi in tempo reale. Se per la coda per la quale \u00e8 impostato lo scambio per i messaggi rifiutati si imposta il valore dell'argomento <code>x-message-ttl<\/code>, i messaggi rifiutati in questa coda <strong>inizieranno ad avere un tempo di vita<\/strong>.<\/li>\n<li><code>x-expires<\/code> \u2014 imposta il valore in millisecondi dopo il quale avviene la cancellazione della coda. La coda pu\u00f2 scadere solo se non ha alcun abbonato. Se ci sono abbonati connessi alla coda, essa potr\u00e0 essere rimossa automaticamente solo quando tutti gli abbonati disconnettono <code>Basic.Cancel<\/code> o si disconnettono. La durata della vita della coda pu\u00f2 terminare solo se non ci sono state richieste <code>Basic.Get<\/code>. Altrimenti, il valore attuale della durata viene azzerato e la coda non verr\u00e0 pi\u00f9 eliminata automaticamente. Inoltre <strong>non ci sono garanzie su quanto rapidamente avvenga la cancellazione della coda dopo la scadenza della sua durata<\/strong>.<\/li>\n<li><code>x-max-length<\/code> \u2014 imposta il numero massimo di messaggi nella coda. Se il numero di messaggi nella coda supera il massimo, i messaggi pi\u00f9 vecchi iniziano ad essere rimossi<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Parte 3. Approfondiamo Queues e Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/738f23dcfdd173a66be619032b46c5cc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li><code>x-max-lenght-bytes<\/code> \u2014 imposta la dimensione massima consentita per il carico utile dei messaggi nella coda. Se viene superato il valore impostato (si \u00e8 verificato un overflow della coda durante la pubblicazione di un messaggio), i messaggi pi\u00f9 vecchi iniziano ad essere rimossi<\/li>\n<li><code>x-overflow<\/code> \u2014 questo argomento \u00e8 utilizzato per configurare il comportamento in caso di overflow della coda. Sono disponibili due valori: <code>drop-head<\/code> (valore predefinito) e <code>reject-publish<\/code>. Se si sceglie <code>drop-head<\/code>, i messaggi pi\u00f9 vecchi verranno eliminati. Se si sceglie <code>reject-publish<\/code>, l'accettazione dei messaggi sar\u00e0 sospesa<\/li>\n<li><code>x-dead-letter-exchange<\/code> \u2014 specifica l'exchange in cui vengono inviati i messaggi rifiutati che non vengono reinseriti in coda<\/li>\n<li><code>x-dead-letter-routing-key<\/code> \u2014 definisce una chiave di instradamento opzionale per i messaggi rifiutati<\/li>\n<li><code>x-max-priority<\/code> \u2014 consente l'ordinamento per priorit\u00e0 nella coda, con un valore massimo di priorit\u00e0 di 255 (RabbitMQ versioni 3.5.0 e successive). Questo numero indica la priorit\u00e0 massima che supporter\u00e0 la coda. Se l'argomento non \u00e8 impostato, la coda non supporter\u00e0 la priorit\u00e0 dei messaggi<\/li>\n<li><code>x-queue-mode<\/code> \u2014 consente di impostare la coda in <strong>modalit\u00e0 pigra<\/strong>. In questa modalit\u00e0 il maggior numero possibile di messaggi verr\u00e0 memorizzato su disco. L'uso della memoria sar\u00e0 minimo. Se non \u00e8 impostato, la coda memorizzer\u00e0 i messaggi in memoria per consegnarli il pi\u00f9 rapidamente possibile<\/li>\n<li><code>x-queue-master-locator<\/code> \u2014 se abbiamo un cluster, \u00e8 possibile impostare una coda master<\/li>\n<li><code>x-ha-policy<\/code> \u2014 utilizzato nella creazione di code HA e definisce come il messaggio sar\u00e0 distribuito tra i nodi. Se \u00e8 impostato il valore <code>all<\/code>, il messaggio sar\u00e0 memorizzato su tutti i nodi. Se \u00e8 impostato il valore <code>nodes<\/code>, il messaggio sar\u00e0 memorizzato su nodi specifici del cluster<\/li>\n<li><code>x-ha-nodes<\/code> \u2014 specifica i nodi a cui appartiene una certa coda <code>HA<\/code><\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Parte 3. Approfondiamo Queues e Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/a8f660b6c0a43626e4025cf7769a4425.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Se la creazione della coda <strong>\u00e8 possibile<\/strong>, il server invier\u00e0 al cliente una risposta sincrona <code>richiesta RPC<\/code> risposta <code>Queue.DeclareOk<\/code>. Se la creazione della coda <strong>non \u00e8 possibile<\/strong> (si \u00e8 verificato un errore nella richiesta <code>Queue.Declare<\/code>), allora <strong>il canale verr\u00e0 chiuso<\/strong> dal server tramite il comando <code>Channel.Close<\/code> e il cliente ricever\u00e0 un'eccezione <noindex><a rel=\"nofollow\" href=\"https:\/\/www.rabbitmq.com\/releases\/rabbitmq-dotnet-client\/v3.6.10\/rabbitmq-dotnet-client-3.6.10-client-htmldoc\/html\/type-RabbitMQ.Client.Exceptions.OperationInterruptedException.html\">OperationInterruptedException<\/a><\/noindex>, che conterr\u00e0 il codice di errore e la sua descrizione. <\/p>\n<p><\/p>\n<p><strong>Una nuova chiamata<\/strong> <code>Queue.Declare<\/code> <strong>con parametri simili<\/strong> restituir\u00e0 informazioni utili su questa coda. Ad esempio, il numero totale di messaggi in attesa in questa coda e il numero totale di consumatori ad essa iscritti. <\/p>\n<p><\/p>\n<p>La chiamata <code>Queue.Declare<\/code> con le credenziali dell'utente a cui non sono stati concessi i privilegi necessari <strong>chiuder\u00e0 il canale<\/strong> utilizzando il comando <code>Channel.Close<\/code> e il cliente ricever\u00e0 un'eccezione <noindex><a rel=\"nofollow\" href=\"https:\/\/www.rabbitmq.com\/releases\/rabbitmq-dotnet-client\/v3.6.10\/rabbitmq-dotnet-client-3.6.10-client-htmldoc\/html\/type-RabbitMQ.Client.Exceptions.OperationInterruptedException.html\">OperationInterruptedException<\/a><\/noindex>, che conterr\u00e0 il codice di errore <noindex><a rel=\"nofollow\" href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/HTTP\/Status\/403\">403<\/a><\/noindex> e la sua descrizione.<\/p>\n<p><\/p>\n<p>Dopo che la coda \u00e8 inattiva per almeno 10 secondi, essa <strong>entra in modalit\u00e0 sleep<\/strong>, attivando la GC nella coda, il che porta a una significativa riduzione della memoria necessaria per questa coda.<\/p>\n<p><\/p>\n<h4 id=\"sozdanie-queue-cherez-graficheskiy-interfeys\"><em>Creazione della Queue tramite l'interfaccia grafica<\/em><\/h4>\n<p><\/p>\n<p>Accediamo al pannello di amministrazione <code>RabbitMQ<\/code> con l'utente <code>guest<\/code> (username: <code>guest<\/code> e password: <code>guest<\/code>). Si prega di notare che l'utente <code>guest<\/code> pu\u00f2 collegarsi solo dall'host locale. Procediamo ora alla scheda <code>Queues<\/code> e facciamo clic su <code>Add a new queue<\/code>. Compiliamo le propriet\u00e0:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Parte 3. Approfondiamo Queues e Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/ea77a406ad16f0871c7197e96a66818f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Non appena inseriamo tutti i dati necessari e facciamo clic su <code>Add queues<\/code>, la coda apparir\u00e0 nell'elenco generale.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Parte 3. Approfondiamo Queues e Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/8342e044a0d6c0a035a2c9f646035cad.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Cliccando sul nome della coda si mostreranno i dettagli. Qui \u00e8 possibile configurare il binding tra l'exchange e la coda, visualizzare l'elenco <code>consumatori<\/code>, pubblicare\/ricevere messaggi, eliminare la coda e visualizzare le statistiche.<\/p>\n<p><\/p>\n<h4 id=\"sozdanie-binding\"><em>Creazione Binding<\/em><\/h4>\n<p><\/p>\n<p>La creazione del binding avviene tramite il comando sincrono <code>richiesta RPC<\/code> al server. La richiesta viene effettuata utilizzando il metodo <code>Queue.Bind<\/code>, chiamato con i seguenti parametri:<\/p>\n<p><\/p>\n<ul>\n<li>nome della coda<\/li>\n<li>nome dell'exchange<\/li>\n<li>altri parametri<\/li>\n<\/ul>\n<p><\/p>\n<p>Esempio di creazione binding utilizzando <noindex><a rel=\"nofollow\" href=\"https:\/\/www.rabbitmq.com\/dotnet.html\">RabbitMQ.Client<\/a><\/noindex>:<\/p>\n<p><\/p>\n<pre><code class=\"cs\">\/\/...\nchannel.QueueBind(\n    queue: queueName,\n    exchange: &quot;my_exchange&quot;,\n    routingKey: &quot;my_key&quot;,\n    arguments: null\n);\n\/\/...<\/code><\/pre>\n<p><\/p>\n<ul>\n<li><code>queue<\/code> \u2014 nome della coda<\/li>\n<li><code>exchange<\/code> \u2014 nome dell'exchange<\/li>\n<li><code>routingKey<\/code> \u2014 chiave di routing<\/li>\n<li><code>argomenti<\/code> \u2014 argomenti opzionali<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Parte 3. Approfondiamo Queues e Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/9123186c94a822309b679f26c2e511ea.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Se la creazione del binding <strong>\u00e8 possibile<\/strong>, il server invier\u00e0 al cliente una risposta sincrona <code>richiesta RPC<\/code> risposta <code>Queue.BindOk<\/code>.<\/p>\n<p><\/p>\n<h4 id=\"sozdanie-binding-cherez-graficheskiy-interfeys\"><em>Creazione Binding tramite interfaccia grafica<\/em><\/h4>\n<p><\/p>\n<p>Accediamo al pannello di amministrazione <code>RabbitMQ<\/code> con l'utente <code>guest<\/code> (username: <code>guest<\/code> e password: <code>guest<\/code>). Si prega di notare che l'utente <code>guest<\/code> pu\u00f2 collegarsi solo dall'host locale. Procediamo ora alla scheda <code>Queues<\/code> e clicchiamo sulla coda <code>my_queue<\/code>. Compilando i campi della sezione <code>bindings<\/code>:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Parte 3. Approfondiamo Queues e Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/7db6b42a4f29a1860aabe54ade0b6833.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Appena inseriamo tutti i dati necessari e premiamo su <code>Bind<\/code>, il binding verr\u00e0 mostrato nell'elenco generale:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Parte 3. Approfondiamo Queues e Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/499eda8e8cb061e6feb75c471eb64b92.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h3 id=\"code\">Code<\/h3>\n<p><\/p>\n<p>In questa sezione descriveremo la coda e il binding usando il codice C#, come se dovessimo sviluppare una libreria. Questo potrebbe essere utile per la comprensione.<\/p>\n<p><\/p>\n<pre><code class=\"cs\">public interface IQueue\n    {        \n        string Name { get; }\n\n        \/\/ <summary>\n        \/\/     Se impostato su true, la queue sar\u00e0 persistente. \n        \/\/     Sar\u00e0 memorizzata su disco e in grado di \n        \/\/     sopravvivere al riavvio del server\/broker. \n        \/\/     Se false, la queue sar\u00e0 temporanea e verr\u00e0 eliminata, \n        \/\/     quando il server\/broker verr\u00e0 riavviato\n        \/\/ <\/summary>\n        bool IsDurable { get; }\n\n        \/\/ <summary>\n        \/\/     Se true, \n        \/\/     questa coda consentir\u00e0 la connessione \n        \/\/     solo a un consumer\n        \/\/ <\/summary>\n        bool IsExclusive { get; }\n\n        \/\/ <summary>\n        \/\/     Eliminazione automatica. \n        \/\/     La coda sar\u00e0 rimossa quando tutti i client si disconnettono.\n        \/\/ <\/summary>\n        bool IsAutoDelete { get; }\n\n        \/\/ <summary>\n        \/\/     Argomenti opzionali\n        \/\/ <\/summary>\n        IDictionary Arguments { get; }\n    }<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"cs\">public class Queue : IQueue\n    {\n        public Queue(\n             string name, \n             bool isDurable = true, \n             bool isExclusive = false, \n             bool isAutoDelete = false, \n             IDictionary&lt;string, object&gt; arguments = null)\n        {\n            Name = name ??\n                throw new ArgumentNullException(name, $&quot;{name} must not be null&quot;);\n\n            IsDurable = isDurable;\n            IsExclusive = isExclusive;\n            IsAutoDelete = isAutoDelete;\n            Arguments = arguments ?? new Dictionary&lt;string, object&gt;();\n        }\n\n        public string Name { get; }\n        public bool IsDurable { get; }\n        public bool IsExclusive { get; }\n        public bool IsAutoDelete { get; }\n        public IDictionary&lt;string, object&gt; Arguments { get; }\n    }<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"cs\">public static class QueueMode\n    {       \n        public const string Default = &quot;default&quot;;\n        \/\/\/ &lt;summary&gt;\n        \/\/\/     \u041b\u0435\u043d\u0438\u0432\u044b\u0439 \u0440\u0435\u0436\u0438\u043c. \u041b\u0435\u043d\u0438\u0432\u044b\u0439 \u0440\u0435\u0436\u0438\u043c \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \n        \/\/\/     \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435, \u0447\u0442\u043e\u0431\u044b \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \n        \/\/\/     \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438\n        \/\/\/ &lt;\/summary&gt;\n        public const string Lazy = &quot;lazy&quot;;\n    }<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"cs\">public interface IBinding\n    {\n        \/\/ <summary>\n        \/\/     Exchange che sar\u00e0 collegato tramite binding\n        \/\/ <\/summary>\n        IExchange Exchange { get; }\n\n        \/\/ <summary>\n        \/\/     Chiave di routing\n        \/\/ <\/summary>\n        string RoutingKey { get; }\n\n        \/\/ <summary>\n        \/\/     Argomenti opzionali\n        \/\/ <\/summary>\n        IDictionary Arguments { get; }\n    }<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"cs\">public class Binding : IBinding\n    {\n        public Binding(\n             IExchange exchange, \n             string routingKey, \n             IDictionary arguments)\n        {\n            Exchange = exchange;\n            RoutingKey = routingKey;\n            Arguments = arguments;\n        }\n\n        public IExchange Exchange { get; }\n        public string RoutingKey { get; }\n        public IDictionary Arguments { get; }\n    }<\/code><\/pre>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/490960\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>Queue (\u043e\u0447\u0435\u0440\u0435\u0434\u044c) \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 \u0438\u043b\u0438 \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0438\u0445 \u043a\u043e\u043f\u0438\u0438 consumers (\u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u043c). Queue \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 Erlang-\u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c (\u0433\u0434\u0435 \u043c\u043e\u0433\u0443\u0442 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u0441\u0430\u043c\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f). 1 \u0442\u044b\u0441\u044f\u0447\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043a\u0430 80Mb. Binding (\u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430) \u2014 \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u043e\u0431\u043c\u0435\u043d\u043d\u0438\u043a\u0443 \u0432 \u043a\u0430\u043a\u0443\u044e \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":73066,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-73065","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"Queue (\u043e\u0447\u0435\u0440\u0435\u0434\u044c) \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 \u0438\u043b\u0438 \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0438\u0445 \u043a\u043e\u043f\u0438\u0438 consumers (\u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u043c). Queue \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 Erlang-\u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c (\u0433\u0434\u0435 \u043c\u043e\u0433\u0443\u0442 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u0441\u0430\u043c\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f). 1 \u0442\u044b\u0441\u044f\u0447\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043a\u0430 80Mb. Binding (\u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430) \u2014 \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u043e\u0431\u043c\u0435\u043d\u043d\u0438\u043a\u0443 \u0432 \u043a\u0430\u043a\u0443\u044e \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47RabbitMQ. \u0427\u0430\u0441\u0442\u044c 3. \u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0441 Queues \u0438 Bindings | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"Queue (\u043e\u0447\u0435\u0440\u0435\u0434\u044c) \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 \u0438\u043b\u0438 \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0438\u0445 \u043a\u043e\u043f\u0438\u0438 consumers (\u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u043c). Queue \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 Erlang-\u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c (\u0433\u0434\u0435 \u043c\u043e\u0433\u0443\u0442 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u0441\u0430\u043c\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f). 1 \u0442\u044b\u0441\u044f\u0447\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043a\u0430 80Mb. Binding (\u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430) \u2014 \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u043e\u0431\u043c\u0435\u043d\u043d\u0438\u043a\u0443 \u0432 \u043a\u0430\u043a\u0443\u044e \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-03-06T17:42:13+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-03-06T17:42:13+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47RabbitMQ. Parte 3. Approfondiamo Queues e Bindings | ProHoster","description":"Queue (coda) \u2014 \u00e8 una struttura dati su disco o in memoria volatile, che memorizza riferimenti ai messaggi e fornisce le loro copie ai consumers (consumatori). La Queue rappresenta un processo Erlang con stato (dove possono essere memorizzati anche i messaggi stessi). 1.000 queue possono occupare circa 80 MB. Binding (binding) \u2014 \u00e8 una regola che informa l'exchange in quale delle queue devono essere inviati i messaggi.","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47RabbitMQ. \u0427\u0430\u0441\u0442\u044c 3. \u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0441 Queues \u0438 Bindings | ProHoster","og:description":"Queue (\u043e\u0447\u0435\u0440\u0435\u0434\u044c) \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 \u0438\u043b\u0438 \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0438\u0445 \u043a\u043e\u043f\u0438\u0438 consumers (\u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u043c). Queue \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 Erlang-\u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c (\u0433\u0434\u0435 \u043c\u043e\u0433\u0443\u0442 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u0441\u0430\u043c\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f). 1 \u0442\u044b\u0441\u044f\u0447\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043a\u0430 80Mb. Binding (\u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430) \u2014 \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u043e\u0431\u043c\u0435\u043d\u043d\u0438\u043a\u0443 \u0432 \u043a\u0430\u043a\u0443\u044e \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.","og:url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-03-06T17:42:13+00:00","article:modified_time":"2020-03-06T17:42:13+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"73065","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 18:41:06","updated":"2022-09-30 05:07:23"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/73065","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=73065"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/73065\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/73066"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=73065"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=73065"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=73065"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}