RabbitMQ. Parte 3. Approfondiamo le Code e i Binding

Coda (coda) — struttura dati su disco o in memoria volatile, che memorizza riferimenti ai messaggi e fornisce le loro copie consumers (ai consumatori). Coda rappresenta Processo Erlang con stato (dove possono essere memorizzati anche i messaggi). 1.000 code possono occupare circa 80 Mb.

Binding (binding) — regola che informa lo scambiatore in quale coda devono andare a finire i messaggi.

Indice

Code temporanee

Se la creazione di una coda avviene con un parametro impostato autoDelete, allora tale coda acquisisce la capacità di eliminarsi automaticamente. 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.

Se la creazione di una coda avviene con un parametro impostato esclusivo, allora tale coda permette di connettersi solo a un consumatore e viene eliminata se il canale si chiude. Finché il canale non si chiude, il cliente può disconnettersi/connettersi, ma solo nell'ambito della stessa connessione. Se il parametro esclusivo è impostato, allora il parametro autoDelete non ha alcun effetto.

Caratteristiche:

  • in caso di interruzione temporanea della connessione, perderemo messaggi che non sono ancora arrivati al consumatore
  • puoi cogliere il fenomeno binding churn. Il fenomeno si verifica quando il numero di operazioni di creazione/eliminazione di code e binding raggiunge valori molto elevati. In modalità cluster, tale flusso di operazioni si estenderà su tutti i nodi e creerà un grande carico. Questo processo può essere ottimizzato controllando il numero di abbonamenti

Code permanenti

Se la creazione di una coda avviene con un parametro impostato durable, allora tale coda mantiene il proprio stato e si ripristina dopo il riavvio del server/broker. Questa coda esisterà fino a quando non verrà invocato il comando Queue.Delete.

Code altamente disponibili

Le code HA richiedono un ambiente cluster RabbitMQ. In modalità cluster, tutte le informazioni su scambi, code, binding e consumatori saranno replicate su tutti i nodi.

Quando un messaggio viene pubblicato in una coda HA, viene memorizzato su ogni nodo relativo alla coda HA. Dopo che il messaggio è stato consumato su uno dei nodi, tutte le copie di quel messaggio verranno eliminate sugli altri nodi.

Le code HA possono estendersi a tutti i nodi in un certo cluster o solo a nodi individuali.

RabbitMQ. Parte 3. Approfondiamo le Code e i Binding

Caratteristiche:

  • 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)

Creazione della coda

La creazione della coda avviene tramite una chiamata sincrona RPC sincrona al server. La richiesta viene effettuata tramite il metodo Queue.Declare, chiamato con i parametri:

  • nome della coda
  • altri parametri

Esempio di creazione della coda tramite RabbitMQ.Client:

// ...
channel.QueueDeclare(
    queue: "my_queue",
    durable: false,
    exclusive: false,
    autoDelete: false,
    arguments: null
);
// ...

  • queue — il nome della coda che desideriamo creare. Il nome deve essere unico e non può coincidere con il nome di sistema della coda
  • durable — se true, la coda sarà mantenere il proprio stato e verrà ripristinata dopo il riavvio del server/broker
  • esclusivo — se true, la coda consentirà solo a un consumatore di collegarsi
  • autoDelete — se true, la coda acquisisce la capacità di eliminarsi automaticamente
  • arguments — argomenti facoltativi. Di seguito analizziamo tutto più nel dettaglio.

arguments

  • x-message-ttl(x-message-time-to-live) — consente di impostare il tempo di scadenza del messaggio in millisecondi. Se la creazione della coda avviene con un valore di argomento stabilito x-message-ttl, allora tale coda sarà escludere automaticamente i messaggi scaduti. Impostare questo valore di argomento x-message-ttl definisce l'età massima per tutti i messaggi in questa coda. Creare una coda di questo tipo consente di evitare di ricevere informazioni obsolete. Questo può essere utilizzato in sistemi in tempo reale. Se una coda per la quale è stato impostato un exchange per i messaggi rifiutati ha un valore di argomento x-message-ttl, allora i messaggi rifiutati in questa coda inizieranno ad avere una vita utile.
  • x-expires — imposta un valore in millisecondi dopo il quale la coda viene eliminata. La coda può esaurire la sua vita utile solo se non ha alcun abbonato. Se ci sono abbonati alla coda, essa potrà eliminarsi automaticamente solo quando tutti gli abbonati chiameranno Basic.Cancel o si disconneteranno. La vita della coda può concludersi solo se non ci sono state richieste Basic.Get. Altrimenti l'attuale valore di impostazione del tempo vita viene azzerato e la coda non verrà più eliminata automaticamente. Inoltre non ci sono garanzie su quanto rapidamente avvenga l'eliminazione della coda dopo la scadenza della sua vita utile.
  • x-max-length — 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ù vecchi.

RabbitMQ. Parte 3. Approfondiamo le Code e i Binding

  • x-max-lenght-bytes — definisce la dimensione massima totale consentita del payload dei messaggi in coda. Se viene superato il valore impostato (si è verificato un overflow della coda durante la pubblicazione di un messaggio), i messaggi più vecchi inizieranno ad essere rimossi.
  • x-overflow — questo argomento viene utilizzato per configurare il comportamento in caso di overflow della coda. Sono disponibili due valori: drop-head (valore predefinito) e reject-publish. Se si sceglie drop-head, i messaggi più vecchi saranno rimossi. Se si sceglie reject-publish, l'accettazione dei messaggi sarà sospesa.
  • x-dead-letter-exchange — definisce l'exchange in cui vengono indirizzati i messaggi rifiutati che non vengono ripubblicati nella coda.
  • x-dead-letter-routing-key — definisce una chiave di routing non obbligatoria per i messaggi rifiutati.
  • x-max-priority — consente l'ordinamento per priorità nella coda con un valore massimo di priorità di 255 (RabbitMQ versioni 3.5.0 e successive). Il numero indica la priorità massima che la coda supporterà. Se l'argomento non è impostato, la coda non supporterà priorità dei messaggi.
  • x-queue-mode — consente di mettere la coda in modalità pigra. In questa modalità il maggior numero possibile di messaggi sarà memorizzato su disco. L'uso della RAM sarà minimo. Se non impostato, la coda memorizzerà i messaggi nella RAM per consegnarli il più rapidamente possibile.
  • x-queue-master-locator — se abbiamo un cluster, possiamo definire la coda master.
  • x-ha-policy — viene utilizzato durante la creazione di code HA e determina come il messaggio sarà distribuito tra i nodi. Se è impostato il valore all, il messaggio sarà salvato su tutti i nodi. Se è impostato il valore nodes, il messaggio sarà salvato su nodi specifici del cluster.
  • x-ha-nodes — definisce i nodi a cui appartiene una certa coda. HA

RabbitMQ. Parte 3. Approfondiamo le Code e i Binding

Se la creazione della coda è possibile, il server invierà al client una risposta sincrona RPC una risposta Queue.DeclareOk. Se la creazione della coda non è possibile (si è verificato un rifiuto della richiesta Queue.Declare), allora il canale verrà chiuso da parte del server utilizzando il comando Channel.Close e il client riceverà un'eccezione OperationInterruptedException, che conterrà un codice di errore e la sua descrizione.

Una chiamata ripetuta Queue.Declare con parametri simili restituirà informazioni utili su questa coda. Ad esempio, il numero totale di messaggi in attesa in questa coda e il numero totale di consumatori iscritti.

Chiamata Queue.Declare sotto le credenziali di un utente a cui non sono stati assegnati i diritti necessari chiuderà il canale utilizzando il comando Channel.Close e il client riceverà un'eccezione OperationInterruptedException, che conterrà il codice di errore 403 e la sua descrizione.

Dopo che la coda rimane inattiva per più di 10 secondi, essa entra in modalità di sospensione, richiamando il GC nella coda, il che porta a una notevole riduzione della memoria necessaria per questa coda.

Creazione di una Queue tramite interfaccia grafica

Accediamo al pannello di amministrazione RabbitMQ come utente guest (username: guest e password: guest). Si prega di notare che l'utente guest può connettersi solo dall'host locale. Ora passiamo alla scheda Code e clicchiamo su Aggiungi una nuova coda. Compiliamo le proprietà:

RabbitMQ. Parte 3. Approfondiamo le Code e i Binding

Una volta che abbiamo inserito tutti i dati necessari e premiamo su Aggiungi code, la coda apparirà nell'elenco generale.

RabbitMQ. Parte 3. Approfondiamo le Code e i Binding

Cliccando sul nome della coda si mostreranno i suoi dettagli. Qui è possibile configurare il binding tra lo scambio e la coda, visualizzare l'elenco consumers, pubblicare/ricevere messaggi, eliminare la coda e visualizzare le statistiche.

Creazione di un Binding

La creazione di un binding avviene tramite RPC sincrona al server. La richiesta viene effettuata tramite il metodo Queue.Bind, chiamato con i parametri:

  • nome della coda
  • nome del punto di scambio
  • altri parametri

Esempio di creazione di un binding tramite RabbitMQ.Client:

//...
channel.QueueBind(
    queue: queueName,
    exchange: "my_exchange",
    routingKey: "my_key",
    arguments: null
);
//...

  • queue — nome della coda
  • exchange — nome dell'exchange
  • routingKey — chiave di routing
  • arguments — argomenti opzionali

RabbitMQ. Parte 3. Approfondiamo le Code e i Binding

Se la creazione del binding è possibile, il server invierà al client una risposta sincrona RPC una risposta Queue.BindOk.

Creazione di un Binding tramite interfaccia grafica

Accediamo al pannello di amministrazione RabbitMQ come utente guest (username: guest e password: guest). Si prega di notare che l'utente guest può connettersi solo dall'host locale. Ora passiamo alla scheda Code e clicchiamo sulla coda my_queue. Compiliamo i campi della sezione bindings:

RabbitMQ. Parte 3. Approfondiamo le Code e i Binding

Una volta che abbiamo inserito tutti i dati necessari e premiamo su Bind, il binding sarà visualizzato nell'elenco generale:

RabbitMQ. Parte 3. Approfondiamo le Code e i Binding

Codice

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.

public interface IQueue
    {        
        string Name { get; }

        // 
        //     Se impostata su true, la queue sarà permanente. 
        //     Sarà conservata su disco e potrà 
        //     sopravvivere al riavvio del server/broker. 
        //     Se impostata su false, la queue è temporanea e sarà eliminata, 
        //     quando il server/broker viene riavviato
        // 
        bool IsDurable { get; }

        // 
        //     Se impostato su true, 
        //     tale coda consentirà di connettersi 
        //     solo a un consumer
        // 
        bool IsExclusive { get; }

        // 
        //     Eliminazione automatica. 
        //     La coda sarà eliminata quando tutti i client si disconnetteranno.
        // 
        bool IsAutoDelete { get; }

        // 
        //     Argomenti opzionali
        // 
        IDictionary Arguments { get; }
    }

public class Queue : IQueue
    {
        public Queue(
             string name, 
             bool isDurable = true, 
             bool isExclusive = false, 
             bool isAutoDelete = false, 
             IDictionary arguments = null)
        {
            Name = name ??
                throw new ArgumentNullException(name, $"{name} non può essere nullo");

            IsDurable = isDurable;
            IsExclusive = isExclusive;
            IsAutoDelete = isAutoDelete;
            Arguments = arguments ?? new Dictionary();
        }

        public string Name { get; }
        public bool IsDurable { get; }
        public bool IsExclusive { get; }
        public bool IsAutoDelete { get; }
        public IDictionary Arguments { get; }
    }

public static class QueueMode
    {       
        public const string Default = "default";
        // <summary>
        //     Modalità pigra. La modalità pigra farà in modo di salvare 
        //     il maggior numero possibile di messaggi su disco, al fine di ridurre 
        //     l'uso della memoria operativa
        // </summary>
        public const string Lazy = "lazy";
    }

public interface IBinding
    {
        // <summary>
        //     Scambio che sarà collegato tramite binding
        // </summary>
        IExchange Exchange { get; }

        // <summary>
        //     Chiave di instradamento
        // </summary>
        string RoutingKey { get; }

        // <summary>
        //     Argomenti opzionali
        // </summary>
        IDictionary Arguments { get; }
    }

public class Binding : IBinding
    {
        public Binding(
             IExchange exchange, 
             string routingKey, 
             IDictionary arguments)
        {
            Exchange = exchange;
            RoutingKey = routingKey;
            Arguments = arguments;
        }

        public IExchange Exchange { get; }
        public string RoutingKey { get; }
        public IDictionary Arguments { get; }
    }

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster