Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Usare una coda che funge da buffer tra un'operazione e il servizio che richiama. Questo approccio semplifica carichi pesanti intermittenti che potrebbero causare un errore del servizio o il timeout dell'attività. Consente di ridurre al minimo l'effetto dei picchi di domanda sulla disponibilità e sulla velocità di risposta dell'attività e del servizio.
Contesto e problema
Molte soluzioni nel cloud eseguono attività che richiamano i servizi. In questo ambiente, carichi pesanti intermittenti possono causare problemi di prestazioni o affidabilità per un servizio.
Un servizio potrebbe far parte della stessa soluzione delle attività che lo usano o potrebbe essere un servizio partner che fornisce l'accesso alle risorse usate di frequente. Esempi di questi tipi di servizi includono una cache o un servizio di archiviazione. Quando più attività vengono eseguite contemporaneamente e usano lo stesso servizio, è difficile prevedere il volume di richieste in qualsiasi momento.
Un servizio potrebbe subire picchi di domanda che lo sovraccaricano e gli impediscono di rispondere rapidamente alle richieste. Sovraccaricare un servizio con molte richieste concorrenti può anche causarne l'interruzione se non è in grado di gestire la contesa generata da tali richieste.
Soluzione
Posiziona una coda tra il task e il servizio. L'attività e il servizio vengono eseguiti in modo asincrono. L'attività invia un messaggio contenente i dati richiesti dal servizio alla coda. La coda funge da buffer e archivia il messaggio finché il servizio non lo recupera. Il servizio recupera i messaggi dalla coda e li elabora. Le richieste provenienti da più attività, che possono essere generate a velocità altamente variabili, possono essere passate al servizio tramite la stessa coda di messaggi. Il diagramma seguente illustra come una coda può livellare il carico in un servizio.
La coda separa le attività dal servizio in modo che il servizio possa gestire i messaggi al proprio ritmo anche quando le attività simultanee generano un volume elevato di richieste. Inoltre, le attività non subiscono ritardi se il servizio non è disponibile quando inviano messaggi alla coda.
Questo modello offre i vantaggi seguenti:
Aiuta a massimizzare la disponibilità perché i ritardi del servizio non influiscono né immediatamente né direttamente sull’applicazione. L'applicazione può continuare a pubblicare messaggi nella coda anche quando il servizio non è disponibile o non elabora i messaggi.
Consente di ottimizzare la scalabilità perché il numero di code e il numero di servizi può variare per soddisfare la domanda.
Consente di controllare i costi perché sono necessarie solo istanze di servizio sufficienti per soddisfare i requisiti per un carico medio anziché per il carico di picco.
Annotazioni
Alcuni servizi implementano la limitazione quando la domanda raggiunge una soglia che potrebbe causare un errore di sistema. Il throttling può ridurre la funzionalità disponibile. Implementare il livellamento del carico in questi servizi per garantire che la domanda non raggiunga questa soglia.
Problemi e considerazioni
Quando si decide come implementare questo modello, tenere presente quanto segue:
Implementare la logica dell'applicazione che controlla la frequenza con cui i servizi gestiscono i messaggi per evitare di sovraccaricare la risorsa di destinazione. Evitare di passare i picchi di domanda alla fase successiva del sistema. Testare il sistema sottoposto a carico per assicurarsi che fornisca il livellamento richiesto. Per ottenere il bilanciamento richiesto, regolare il numero di code e il numero di istanze di servizio che gestiscono i messaggi.
Le code di messaggi sono un meccanismo di comunicazione unidirezionale. Se un'attività prevede una risposta da un servizio, potrebbe essere necessario implementare un meccanismo che il servizio può usare per inviare una risposta. Per ulteriori informazioni, vedere le opzioni di messaggistica asincrona in Azure.
La scalabilità automatica, senza limitare la velocità downstream aggregata dei consumer, non fa che spostare il sovraccarico alle dipendenze downstream. Questo overload può aumentare la contesa per le risorse condivise da questi servizi e ridurre l'efficacia della coda per livellare il carico.
Se il tasso medio di produzione supera il tasso di consumo, la coda continua a crescere e la latenza aumenta. Monitorare la profondità della coda e ridimensionare i consumer entro limiti sicuri o lavorare al produttore.
Questo modello dipende dalla durabilità della coda per evitare la perdita di messaggi. Se il broker non salva i messaggi in una memoria di archiviazione persistente, un arresto anomalo o un limite di capacità può causare la perdita dei dati accodati prima che i processi consumer li elaborino. Scegliere un servizio di accodamento che rende persistenti i messaggi nel disco o nell'archiviazione replicata e comprenderne le quote di dimensioni e i limiti di conservazione. Per i carichi di lavoro per i quali è necessario che i messaggi resistano a guasti regionali, valutare le opzioni di disaster recovery geografico.
La maggior parte dei servizi di accodamento recapita messaggi con semantica at-least-once, il che significa che i consumer possono ricevere lo stesso messaggio più di una volta. Progettare la logica consumer in modo che sia idempotente in modo che l'elaborazione dello stesso messaggio più volte produa lo stesso risultato ed eviti problemi come record duplicati o addebiti ripetuti.
Alcuni messaggi non possono essere elaborati perché contengono dati in formato non valido, fanno riferimento a risorse mancanti o attivano errori permanenti. Invece di lasciare che questi messaggi continuino a circolare all’infinito e blocchino la coda, instradateli in una coda dei messaggi non recapitabili. Monitorare la profondità della coda dei messaggi non recapitabili in modo che il team operativo possa analizzare gli errori, correggere il problema sottostante e inviare di nuovo i messaggi quando appropriato.
L'introduzione di una coda tra un produttore e un consumatore non mantiene l'ordine originale di invio in ogni circostanza, soprattutto quando più consumatori elaborano i messaggi in parallelo. Se il carico di lavoro richiede un ordinamento rigoroso, usare funzionalità come message sessions in bus di servizio di Azure. Se non è necessario un ordinamento rigoroso, progettare i consumer in modo che possano gestire i messaggi in qualsiasi ordine, semplificando la scalabilità.
Quando usare questo modello
Usare questo modello quando:
Il carico di lavoro presenta picchi intermittenti che possono sovraccaricare i servizi downstream.
È necessario separare l'assunzione di richieste dalla velocità effettiva di elaborazione per migliorare la resilienza e il controllo dei costi.
Questo modello potrebbe non essere adatto quando:
Il chiamante richiede una risposta sincrona a bassa latenza.
Il volume del carico di lavoro è prevedibilmente basso e stabile, quindi l'aggiunta di complessità di accodamento offre un vantaggio minimo.
Progettazione del carico di lavoro
Valutare come usare il modello di livellamento del carico di Queue-Based nella progettazione di un carico di lavoro per soddisfare gli obiettivi e i principi trattati nei pilastri di Azure Well-Architected Framework. La tabella seguente fornisce indicazioni su come questo modello supporta gli obiettivi di ogni pilastro.
| Pilastro | Come questo modello supporta gli obiettivi di pilastro |
|---|---|
| decisioni di progettazione dell'affidabilità consentono al carico di lavoro di diventare resiliente a un malfunzionamento e assicurano che ripristini a uno stato completamente funzionante dopo che si verifica un guasto. | L'approccio descritto da questo modello può fornire resilienza contro picchi improvvisi della domanda separando l'arrivo delle attività dalla loro elaborazione. Può anche isolare i malfunzionamenti nell'elaborazione della coda in modo che non influiscano sulla ricezione. - RE:06 Scaling |
| L'ottimizzazione dei costi è incentrata sul mantenimento e sul miglioramento del ritorno del carico di lavoro sugli investimenti. | Poiché l'elaborazione del carico è disaccoppiata dall'assunzione di richieste o attività, è possibile usare questo approccio per ridurre la necessità di effettuare il overprovisioning delle risorse per gestire il carico di picco. - CO:12 Costi di ridimensionamento |
| l'efficienza delle prestazioni consente al carico di lavoro soddisfare in modo efficiente le richieste tramite ottimizzazioni di ridimensionamento, dati e codice. | Questo approccio consente di progettare intenzionalmente le prestazioni della velocità effettiva perché l'assunzione di richieste non deve correlare con la velocità di elaborazione. - PE:05 Ridimensionamento e partizionamento |
Se questo modello introduce compromessi all'interno di un pilastro, considerarli contro gli obiettivi degli altri pilastri.
Esempio
Un'app Web scrive dati in un archivio dati esterno. Se più istanze dell'app Web sono in esecuzione contemporaneamente, l'archivio dati potrebbe non essere in grado di rispondere alle richieste con sufficiente rapidità, causando il timeout delle richieste, la loro limitazione o il loro mancato completamento per altri motivi. Il diagramma seguente mostra un archivio dati sovraccaricato da richieste simultanee da istanze di un'applicazione.
Per risolvere questo problema, usare una coda per livellare il carico tra le istanze dell'applicazione e l'archivio dati. Un'app Funzioni di Azure legge i messaggi da una coda di bus di servizio ed esegue le richieste di lettura/scrittura all'archivio dati. Funzioni di Azure può ridimensionare le istanze in base al backlog di bus di servizio usando il ridimensionamento basato sulla destinazione, entro i limiti di scalabilità configurati. È anche possibile ottimizzare le impostazioni di concorrenza dei trigger per proteggere l'archivio dati. Per indicazioni sull'implementazione, vedi Ridimensionamento basato sulla destinazione e Limitare il ridimensionamento orizzontale. Senza questa ottimizzazione, il livello dei processi di lavoro può reintrodurre contesa nel back-end.
Come variazione tecnologica, è possibile implementare lo stesso modello usando App contenitore di Azure anziché Funzioni di Azure. In questo approccio, un worker containerizzato elabora i messaggi da bus di servizio e scrive nell'archivio dati. Container Apps ridimensiona il worker in un intervallo compreso tra il numero minimo e massimo di repliche configurate, in base alle regole di scalabilità relative alla coda. È anche possibile implementare lo stesso approccio usando archiviazione code di Azure come origine evento. Per indicazioni sull'implementazione, vedere Impostare le regole di ridimensionamento in App contenitore e Distribuire un processo basato su eventi usando App contenitore.
Passaggi successivi
Quando si implementa questo modello, possono essere rilevanti anche le indicazioni seguenti:
Opzioni di messaggistica asincrona in Azure: le code di messaggi sono intrinsecamente asincrone. Potrebbe essere necessario riprogettare la logica dell'applicazione di un'attività se comunica direttamente con un servizio. Analogamente, potrebbe essere necessario effettuare il refactoring di un servizio per accettare le richieste da una coda di messaggi.
Scegliere tra i servizi di messaggistica Azure: ottenere altre informazioni per scegliere un meccanismo di messaggistica e accodamento nelle applicazioni Azure.
Raccomandazioni per lo sviluppo di processi in background: applicare questo modello ai processi in background in modo che le code di messaggi possano archiviare le richieste per le attività in background quando l'applicazione presenta un carico elevato.
Stile architetturale Web-Queue-Worker: il Web e il processo worker sono entrambi privi di stato. Lo stato della sessione può essere archiviato in una cache distribuita. Il processo worker esegue attività di lunga durata in modo asincrono e può essere attivato da messaggi nella coda oppure eseguito in base a una pianificazione per l'elaborazione batch.
Risorse correlate
Modello dei consumer concorrenti: potrebbe essere possibile eseguire più istanze di un servizio, ciascuna delle quali funge da consumatore di messaggi dalla coda di bilanciamento del carico. È possibile usare questo approccio per regolare la frequenza con cui i messaggi vengono ricevuti e passati a un servizio.
Modello di limitazione: un modo semplice per implementare la limitazione in un servizio consiste nell'usare il livellamento del carico basato su coda e instradare tutte le richieste a un servizio tramite una coda di messaggi. Il servizio può elaborare le richieste a una velocità che garantisce che non esaurisca le risorse necessarie e riduce la quantità di conflitti possibili.