{"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 le Code e i Binding","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><code>Coda<\/code> (coda) \u2014 struttura dati su disco o in memoria volatile, che memorizza riferimenti ai messaggi e fornisce le loro copie <code>consumers<\/code> (ai consumatori). <code>Coda<\/code> rappresenta <noindex><a rel=\"nofollow\" href=\"http:\/\/erlang.org\/doc\/reference_manual\/processes.html\">Processo Erlang<\/a><\/noindex> con stato (dove possono essere memorizzati anche i messaggi). 1.000 code possono occupare circa 80 Mb.<\/p>\n<p><\/p>\n<p><code>Binding<\/code> (binding) \u2014 regola che informa lo scambiatore in quale coda devono andare a finire 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 le Code e i Binding<\/a><\/noindex><\/li>\n<li>RabbitMQ. Parte 4. Approfondiamo 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 dei moduli Federation e Shovel<\/li>\n<li>RabbitMQ. Parte 7. Dettagli su Connessione e Canale<\/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 un parametro impostato <code>autoDelete<\/code>, allora tale coda acquisisce la capacit\u00e0 <strong>di eliminarsi automaticamente<\/strong>. Tali code vengono solitamente create nel momento in cui si connette il primo cliente e vengono eliminate nel momento in cui tutti i clienti si disconnettono. <\/p>\n<p><\/p>\n<p>Se la creazione di una coda avviene con un parametro impostato <code>esclusivo<\/code>, allora tale coda <strong>permette di connettersi solo a un consumatore<\/strong> e viene eliminata se il canale si chiude. Finch\u00e9 il canale non si chiude, il cliente pu\u00f2 disconnettersi\/connettersi, ma solo nell'ambito della stessa connessione. Se il parametro <code>esclusivo<\/code> \u00e8 impostato, allora 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 interruzione temporanea della connessione, perderemo messaggi che non sono ancora arrivati al consumatore<\/li>\n<li>puoi cogliere il fenomeno <code>binding churn<\/code>. Il fenomeno si verifica quando il numero di operazioni di creazione\/eliminazione di code e binding raggiunge valori molto elevati. In modalit\u00e0 cluster, tale flusso di operazioni si estender\u00e0 su tutti i nodi e creer\u00e0 un grande carico. Questo processo pu\u00f2 essere ottimizzato controllando il numero di abbonamenti<\/li>\n<\/ul>\n<p><\/p>\n<h4 id=\"postoyannye-ocheredi\"><em>Code permanenti<\/em><\/h4>\n<p><\/p>\n<p>Se la creazione di una coda avviene con un 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 fino a quando non verr\u00e0 invocato il comando <code>Queue.Delete<\/code>. <\/p>\n<p><\/p>\n<h4 id=\"highly-available-ocheredi\"><em>Code altamente disponibili<\/em><\/h4>\n<p><\/p>\n<p>Le code HA richiedono un ambiente cluster RabbitMQ. In modalit\u00e0 cluster, tutte le informazioni su scambi, code, binding 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 ogni nodo relativo alla 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 individuali. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Parte 3. Approfondiamo le Code e i Binding\" 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 porta a penalizzazioni nelle prestazioni. Quando si inserisce un messaggio in una certa coda HA o quando si consuma un messaggio da una coda HA, RabbitMQ deve eseguire la coordinazione tra tutti i nodi (2-3 nodi di solito sono 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 chiamata sincrona <code>RPC<\/code> sincrona al server. La richiesta viene effettuata tramite il metodo <code>Queue.Declare<\/code>, chiamato con i 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 della coda tramite <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 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>mantenere il proprio stato<\/strong> e verr\u00e0 ripristinata dopo il riavvio del server\/broker<\/li>\n<li><code>esclusivo<\/code> \u2014 se true, la coda consentir\u00e0 solo a un consumatore di collegarsi<\/li>\n<li><code>autoDelete<\/code> \u2014 se true, la coda acquisisce la capacit\u00e0 <strong>di eliminarsi automaticamente<\/strong><\/li>\n<li><code>arguments<\/code> \u2014 argomenti facoltativi. Di seguito analizziamo tutto pi\u00f9 nel dettaglio.<\/li>\n<\/ul>\n<p><\/p>\n<h5 id=\"arguments\"><em>arguments<\/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 creazione della coda avviene con un valore di argomento stabilito <code>x-message-ttl<\/code>, allora tale coda sar\u00e0 <strong>escludere automaticamente i messaggi scaduti<\/strong>. Impostare questo valore di argomento <code>x-message-ttl<\/code> definisce l'et\u00e0 massima per tutti i messaggi in questa coda. Creare una coda di questo tipo <strong>consente di evitare di ricevere informazioni obsolete<\/strong>. Questo pu\u00f2 essere utilizzato in sistemi in tempo reale. Se una coda per la quale \u00e8 stato impostato un exchange per i messaggi rifiutati ha un valore di argomento <code>x-message-ttl<\/code>, allora i messaggi rifiutati in questa coda <strong>inizieranno ad avere una vita utile<\/strong>.<\/li>\n<li><code>x-expires<\/code> \u2014 imposta un valore in millisecondi dopo il quale la coda viene eliminata. La coda pu\u00f2 esaurire la sua vita utile solo se non ha alcun abbonato. Se ci sono abbonati alla coda, essa potr\u00e0 eliminarsi automaticamente solo quando tutti gli abbonati chiameranno <code>Basic.Cancel<\/code> o si disconneteranno. La vita della coda pu\u00f2 concludersi solo se non ci sono state richieste <code>Basic.Get<\/code>. Altrimenti l'attuale valore di impostazione del tempo vita viene azzerato e la coda non verr\u00e0 pi\u00f9 eliminata automaticamente. Inoltre <strong>non ci sono garanzie su quanto rapidamente avvenga l'eliminazione della coda dopo la scadenza della sua vita utile<\/strong>.<\/li>\n<li><code>x-max-length<\/code> \u2014 definisce il numero massimo di messaggi in coda. Se il numero di messaggi nella coda supera il numero massimo, inizieranno ad essere rimossi i messaggi pi\u00f9 vecchi.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Parte 3. Approfondiamo le Code e i Binding\" 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 definisce la dimensione massima totale consentita del payload dei messaggi in 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 inizieranno ad essere rimossi.<\/li>\n<li><code>x-overflow<\/code> \u2014 questo argomento viene 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 saranno rimossi. Se si sceglie <code>reject-publish<\/code>, l'accettazione dei messaggi sar\u00e0 sospesa.<\/li>\n<li><code>x-dead-letter-exchange<\/code> \u2014 definisce l'exchange in cui vengono indirizzati i messaggi rifiutati che non vengono ripubblicati nella coda.<\/li>\n<li><code>x-dead-letter-routing-key<\/code> \u2014 definisce una chiave di routing non obbligatoria 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). Il numero indica la priorit\u00e0 massima che la coda supporter\u00e0. Se l'argomento non \u00e8 impostato, la coda non supporter\u00e0 priorit\u00e0 dei messaggi.<\/li>\n<li><code>x-queue-mode<\/code> \u2014 consente di mettere la coda in <strong>modalit\u00e0 pigra<\/strong>. In questa modalit\u00e0 il maggior numero possibile di messaggi sar\u00e0 memorizzato su disco. L'uso della RAM sar\u00e0 minimo. Se non impostato, la coda memorizzer\u00e0 i messaggi nella RAM per consegnarli il pi\u00f9 rapidamente possibile.<\/li>\n<li><code>x-queue-master-locator<\/code> \u2014 se abbiamo un cluster, possiamo definire la coda master.<\/li>\n<li><code>x-ha-policy<\/code> \u2014 viene utilizzato durante la creazione di code HA e determina come il messaggio sar\u00e0 distribuito tra i nodi. Se \u00e8 impostato il valore <code>all<\/code>, il messaggio sar\u00e0 salvato su tutti i nodi. Se \u00e8 impostato il valore <code>nodes<\/code>, il messaggio sar\u00e0 salvato su nodi specifici del cluster.<\/li>\n<li><code>x-ha-nodes<\/code> \u2014 definisce 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 le Code e i Binding\" 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 client una risposta sincrona <code>RPC<\/code> una risposta <code>Queue.DeclareOk<\/code>. Se la creazione della coda <strong>non \u00e8 possibile<\/strong> (si \u00e8 verificato un rifiuto della richiesta <code>Queue.Declare<\/code>), allora <strong>il canale verr\u00e0 chiuso<\/strong> da parte del server utilizzando il comando <code>Channel.Close<\/code> e il client 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 un codice di errore e la sua descrizione. <\/p>\n<p><\/p>\n<p><strong>Una chiamata ripetuta<\/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 iscritti. <\/p>\n<p><\/p>\n<p>Chiamata <code>Queue.Declare<\/code> sotto le credenziali di un utente a cui non sono stati assegnati i diritti necessari <strong>chiuder\u00e0 il canale<\/strong> utilizzando il comando <code>Channel.Close<\/code> e il client 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 rimane inattiva per pi\u00f9 di 10 secondi, essa <strong>entra in modalit\u00e0 di sospensione<\/strong>, richiamando il GC nella coda, il che porta a una notevole riduzione della memoria necessaria per questa coda.<\/p>\n<p><\/p>\n<h4 id=\"sozdanie-queue-cherez-graficheskiy-interfeys\"><em>Creazione di una Queue tramite interfaccia grafica<\/em><\/h4>\n<p><\/p>\n<p>Accediamo al pannello di amministrazione <code>RabbitMQ<\/code> come 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 connettersi solo dall'host locale. Ora passiamo alla scheda <code>Code<\/code> e clicchiamo su <code>Aggiungi una nuova coda<\/code>. Compiliamo le propriet\u00e0:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Parte 3. Approfondiamo le Code e i Binding\" src=\"\/wp-content\/uploads\/2020\/03\/ea77a406ad16f0871c7197e96a66818f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Una volta che abbiamo inserito tutti i dati necessari e premiamo su <code>Aggiungi code<\/code>, la coda apparir\u00e0 nell'elenco generale.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Parte 3. Approfondiamo le Code e i Binding\" 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 suoi dettagli. Qui \u00e8 possibile configurare il binding tra lo scambio e la coda, visualizzare l'elenco <code>consumers<\/code>, pubblicare\/ricevere messaggi, eliminare la coda e visualizzare le statistiche.<\/p>\n<p><\/p>\n<h4 id=\"sozdanie-binding\"><em>Creazione di un Binding<\/em><\/h4>\n<p><\/p>\n<p>La creazione di un binding avviene tramite <code>RPC<\/code> sincrona al server. La richiesta viene effettuata tramite il metodo <code>Queue.Bind<\/code>, chiamato con i parametri:<\/p>\n<p><\/p>\n<ul>\n<li>nome della coda<\/li>\n<li>nome del punto di scambio<\/li>\n<li>altri parametri<\/li>\n<\/ul>\n<p><\/p>\n<p>Esempio di creazione di un binding tramite <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>arguments<\/code> \u2014 argomenti opzionali<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Parte 3. Approfondiamo le Code e i Binding\" 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 client una risposta sincrona <code>RPC<\/code> una risposta <code>Queue.BindOk<\/code>.<\/p>\n<p><\/p>\n<h4 id=\"sozdanie-binding-cherez-graficheskiy-interfeys\"><em>Creazione di un Binding tramite interfaccia grafica<\/em><\/h4>\n<p><\/p>\n<p>Accediamo al pannello di amministrazione <code>RabbitMQ<\/code> come 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 connettersi solo dall'host locale. Ora passiamo alla scheda <code>Code<\/code> e clicchiamo sulla coda <code>my_queue<\/code>. Compiliamo i campi della sezione <code>bindings<\/code>:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Parte 3. Approfondiamo le Code e i Binding\" src=\"\/wp-content\/uploads\/2020\/03\/7db6b42a4f29a1860aabe54ade0b6833.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Una volta che abbiamo inserito tutti i dati necessari e premiamo su <code>Bind<\/code>, il binding sar\u00e0 visualizzato nell'elenco generale:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Parte 3. Approfondiamo le Code e i Binding\" src=\"\/wp-content\/uploads\/2020\/03\/499eda8e8cb061e6feb75c471eb64b92.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h3 id=\"code\">Codice<\/h3>\n<p><\/p>\n<p>In questa sezione descriviamo la coda e il binding con codice in C#, come se dovessimo sviluppare una libreria. 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 impostata su true, la queue sar\u00e0 permanente. \n        \/\/     Sar\u00e0 conservata su disco e potr\u00e0 \n        \/\/     sopravvivere al riavvio del server\/broker. \n        \/\/     Se impostata su false, la queue \u00e8 temporanea e sar\u00e0 eliminata, \n        \/\/     quando il server\/broker viene riavviato\n        \/\/ <\/summary>\n        bool IsDurable { get; }\n\n        \/\/ <summary>\n        \/\/     Se impostato su true, \n        \/\/     tale coda consentir\u00e0 di connettersi \n        \/\/     solo a un consumer\n        \/\/ <\/summary>\n        bool IsExclusive { get; }\n\n        \/\/ <summary>\n        \/\/     Eliminazione automatica. \n        \/\/     La coda sar\u00e0 eliminata quando tutti i client si disconnetteranno.\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 arguments = null)\n        {\n            Name = name ??\n                throw new ArgumentNullException(name, $\"{name} deve essere non nullo\");\n\n            IsDurable = isDurable;\n            IsExclusive = isExclusive;\n            IsAutoDelete = isAutoDelete;\n            Arguments = arguments ?? new Dictionary().\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 Arguments { get; }\n    }<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"cs\">public static class QueueMode\n    {       \n        public const string Default = \"default\";\n        \/\/ <summary>\n        \/\/     Modalit\u00e0 pigra. La modalit\u00e0 pigra costringer\u00e0 a salvare \n        \/\/     il maggior numero possibile di messaggi su disco per ridurre \n        \/\/     l'uso della memoria\n        \/\/ <\/summary>\n        public const string Lazy = \"lazy\";\n    }<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"cs\">public interface IBinding\n    {\n        \/\/ &lt;summary&gt;\n        \/\/     Scambio che sar\u00e0 collegato tramite binding\n        \/\/ &lt;\/summary&gt;\n        IExchange Exchange { get; }\n\n        \/\/ &lt;summary&gt;\n        \/\/     Chiave di instradamento\n        \/\/ &lt;\/summary&gt;\n        string RoutingKey { get; }\n\n        \/\/ &lt;summary&gt;\n        \/\/     Argomenti opzionali\n        \/\/ &lt;\/summary&gt;\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 5.0.1.1 - 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).\" \/>\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) 5.0.1.1\" \/>\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).\" \/>\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. Esploriamo le Queues e i Bindings | ProHoster","description":"La Queue (coda) \u00e8 una struttura dati su disco o nella memoria operativa che conserva riferimenti ai messaggi e ne fornisce delle copie ai consumers (consumatori).","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).","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","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"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}]}}