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.
Tutte le applicazioni che comunicano con servizi e risorse remoti devono essere sensibili agli errori temporanei. Ciò è particolarmente vero per le applicazioni eseguite nel cloud, dove, a causa della natura dell'ambiente e della connettività Internet, è probabile che questo tipo di errore venga riscontrato più spesso. Gli errori temporanei includono la perdita momentanea di connettività di rete a componenti e servizi, la temporanea indisponibilità di un servizio e i timeout che si verificano quando un servizio è occupato. Questi errori spesso si correggono automaticamente, quindi, se l'azione viene ripetuta dopo un adeguato ritardo, è probabile che abbia successo.
Questo articolo fornisce indicazioni generali per la gestione degli errori temporanei.
Perché si verificano errori temporanei nel cloud?
Gli errori temporanei possono verificarsi in qualsiasi ambiente, su qualsiasi piattaforma o sistema operativo e in qualsiasi tipo di applicazione. Per le soluzioni eseguite nell'infrastruttura locale locale, le prestazioni e la disponibilità dell'applicazione e dei relativi componenti vengono in genere mantenute tramite ridondanza hardware costosa e spesso sottoutilata e i componenti e le risorse si trovano vicini tra loro. Questo approccio rende meno probabile l'errore, ma possono verificarsi errori temporanei, in quanto possono verificarsi interruzioni causate da eventi imprevisti come l'alimentatore esterno o i problemi di rete o altri scenari di emergenza.
L'hosting cloud, inclusi i sistemi cloud privati, può offrire una maggiore disponibilità complessiva usando risorse condivise, ridondanza, failover automatico e allocazione dinamica delle risorse in molti nodi di calcolo di base. Tuttavia, a causa della natura degli ambienti cloud, è più probabile che si verifichino errori temporanei. Esistono diversi motivi per questo:
Molte risorse in un ambiente cloud vengono condivise e l'accesso a queste risorse è soggetto a limitazioni per proteggere le risorse. Alcuni servizi rifiutano le connessioni quando il carico aumenta a un livello specifico o quando viene raggiunta una velocità effettiva massima, per consentire l'elaborazione delle richieste esistenti e mantenere le prestazioni del servizio per tutti gli utenti. Il controllo della larghezza di banda aiuta a mantenere la qualità del servizio per i vicini e le altre utenze che utilizzano la risorsa condivisa.
Gli ambienti cloud usano un numero elevato di unità hardware di base. Offrono prestazioni distribuendo dinamicamente il carico tra più unità di calcolo e componenti dell'infrastruttura. Offrono affidabilità riciclando o sostituendo automaticamente le unità non riuscite. A causa di questa natura dinamica, possono occasionalmente verificarsi guasti transitori e temporanei errori di connessione.
Sono spesso presenti più componenti hardware, tra cui l'infrastruttura di rete, ad esempio router e servizi di bilanciamento del carico, tra l'applicazione e le risorse e i servizi usati. Questa infrastruttura aggiuntiva può talvolta introdurre altri errori di connessione e latenza di connessione temporanei.
Le condizioni di rete tra il client e il server potrebbero essere variabili, soprattutto quando la comunicazione attraversa Internet. Anche nelle posizioni locali, i carichi di traffico pesanti possono rallentare la comunicazione e causare errori di connessione intermittenti.
Sfide
Gli errori temporanei possono avere un grande effetto sulla disponibilità percepita di un'applicazione, anche se sono stati testati accuratamente in tutte le circostanze prevedibili. Per garantire che le applicazioni ospitate nel cloud funzionino in modo affidabile, è necessario assicurarsi che possano rispondere alle sfide seguenti:
L'applicazione deve essere in grado di rilevare gli errori quando si verificano e determinare se è probabile che siano transitori, di lunga durata o guasti terminali. È probabile che risorse diverse restituiscano risposte diverse quando si verifica un errore e queste risposte possono anche variare a seconda del contesto dell'operazione. Ad esempio, la risposta per un errore quando l'applicazione legge dall'archiviazione potrebbe differire dalla risposta per un errore durante la scrittura nell'archiviazione. Molte risorse e servizi hanno contratti di errore transitorio ben documentati. Tuttavia, quando tali informazioni non sono disponibili, può essere difficile individuare la natura dell'errore e se è probabile che sia temporaneo.
L'applicazione deve essere in grado di ritentare l'operazione se determina che è probabile che l'errore sia temporaneo. Deve inoltre tenere traccia del numero di tentativi di esecuzione dell'operazione.
L'applicazione deve utilizzare una strategia appropriata per i nuovi tentativi. La strategia specifica il numero di tentativi dell'applicazione, il ritardo tra ogni tentativo e le azioni da intraprendere dopo un tentativo fallito. Il numero appropriato di tentativi e il ritardo tra ciascuno di essi sono spesso difficili da determinare. La strategia varia a seconda del tipo di risorsa e delle condizioni operative correnti della risorsa e dell'applicazione.
Linee guida generali
Le seguenti linee guida possono aiutarti a progettare meccanismi di gestione degli errori temporanei adatti alle tue applicazioni.
Determina se è presente un meccanismo di ripetizione integrato
Molti servizi forniscono un SDK o una libreria client che contiene un meccanismo di gestione degli errori temporanei. I criteri di ripetizione dei tentativi utilizzati sono in genere adattati alla natura e ai requisiti del servizio di destinazione. In alternativa, le interfacce REST per i servizi potrebbero restituire informazioni che possono aiutare a determinare se un nuovo tentativo è appropriato e quanto tempo attendere prima del successivo tentativo.
È consigliabile utilizzare il meccanismo di ripetizione dei tentativi integrato quando disponibile, a meno che non si disponga di requisiti specifici e ben compresi che rendano più appropriato un comportamento di ripetizione diverso.
Determina se l'operazione è adatta per riprovare
Esegui le operazioni per un nuovo tentativo solo quando gli errori sono temporanei (in genere indicati dalla natura dell'errore) e quando esiste almeno una certa probabilità che l'operazione abbia esito positivo quando viene ripetuta. Non è possibile ripetere le operazioni che tentano un'operazione non valida, ad esempio un aggiornamento del database a un elemento che non esiste o una richiesta a un servizio o a una risorsa che ha subito un errore irreversibile.
In generale, implementare nuovi tentativi solo quando è possibile determinare l'effetto completo di questa operazione e quando le condizioni sono ben comprensibili e possono essere convalidate. In caso contrario, lasciare che il codice chiamante implementi le ripetizioni. Ricorda che gli errori restituiti da risorse e servizi al di fuori del tuo controllo potrebbero evolversi nel tempo e potrebbe essere necessario rivedere la logica di rilevamento degli errori temporanei.
Quando si creano servizi o componenti, è consigliabile implementare codici di errore e messaggi che consentono ai client di determinare se devono ripetere le operazioni non riuscite. In particolare, indicare se il client deve ritentare l'operazione (ad esempio restituendo un valore isTransient) e suggerire un ritardo appropriato prima del tentativo successivo. Se crei un servizio Web, valuta la possibilità di restituire errori personalizzati definiti nei contratti di servizio. Anche se i client generici potrebbero non essere in grado di leggere questi errori, sono utili per la creazione di client personalizzati.
Determina un conteggio e un intervallo di tentativi appropriati
Ottimizza il conteggio dei tentativi e l'intervallo in base al tipo di caso d'uso. Se non riprovi abbastanza volte, l'applicazione non potrà completare l'operazione e probabilmente fallirà. Se si ritenta un numero eccessivo di tentativi o con un intervallo troppo breve tra tentativi, l'applicazione potrebbe contenere risorse come thread, connessioni e memoria per lunghi periodi, che influiscono negativamente sull'integrità dell'applicazione.
Adatta i valori per l'intervallo di tempo e il numero di tentativi al tipo di operazione. Ad esempio, se l'operazione fa parte di un'interazione con l'utente, l'intervallo dovrebbe essere breve e dovrebbero essere effettuati solo pochi tentativi. Usando questo approccio, è possibile evitare di rendere gli utenti in attesa di una risposta, che contiene connessioni aperte e può ridurre la disponibilità per altri utenti. Se l'operazione fa parte di un flusso di lavoro a esecuzione prolungata o critica, in cui l'annullamento e il riavvio del processo richiede molto tempo, è opportuno attendere più tempo tra i tentativi e riprovare più volte.
Tieni presente che determinare gli intervalli appropriati tra i tentativi è la parte più difficile della progettazione di una strategia di successo. Le strategie tipiche utilizzano i seguenti tipi di intervallo tra i tentativi:
Backoff esponenziale. L'applicazione attende qualche istante prima del primo tentativo e poi aumenta esponenzialmente il tempo tra ogni tentativo successivo. Ad esempio, potrebbe ritentare l'operazione dopo 3 secondi, 12 secondi, 30 secondi e così via.
intervalli incrementali. L'applicazione attende un breve periodo di tempo prima del primo tentativo e quindi aumenta in modo incrementale il tempo tra ogni tentativo successivo. Ad esempio, potrebbe ritentare l'operazione dopo 3 secondi, 7 secondi, 13 secondi e così via.
Intervalli regolari. L'applicazione attende lo stesso periodo di tempo tra ogni tentativo. Ad esempio, potrebbe ritentare l'operazione ogni 3 secondi.
Nuovo tentativo immediato. A volte un errore temporaneo è breve, probabilmente causato da un evento come un conflitto di pacchetti di rete o un picco in un componente hardware. In questo caso, ritentare immediatamente l'operazione è appropriato perché potrebbe avere esito positivo se l'errore viene cancellato nel tempo necessario all'applicazione per assemblare e inviare la richiesta successiva. Tuttavia, non dovrebbe mai esserci più di un tentativo immediato. È consigliabile passare a strategie alternative, ad esempio azioni di back-off esponenziale o di fallback, se il tentativo immediato non riesce.
Sequenza casuale. Una delle strategie di ritentativo elencate in precedenza può includere una casualizzazione per impedire che numerose istanze del client inviino tentativi successivi contemporaneamente. Ad esempio, un'istanza potrebbe ritentare l'operazione dopo 3 secondi, 11 secondi, 28 secondi e così via, mentre un'altra istanza potrebbe ritentare l'operazione dopo 4 secondi, 12 secondi, 26 secondi e così via. La randomizzazione è una tecnica utile che può essere combinata con altre strategie.
Come linea guida generale, usare una strategia di back-off esponenziale per le operazioni in background e usare strategie di ripetizione immediata o a intervalli regolari per le operazioni interattive. In entrambi i casi, è consigliabile scegliere il ritardo e il numero di tentativi in modo che la latenza massima per tutti i tentativi rientri nei requisiti di latenza end-to-end richiesti.
Prendere in considerazione la combinazione di tutti i fattori che contribuiscono al timeout massimo complessivo per un'operazione ritentata. Questi fattori includono il tempo necessario per una connessione non riuscita per produrre una risposta (in genere impostata da un valore di timeout nel client), il ritardo tra i tentativi di ripetizione e il numero massimo di tentativi. La somma di tutti questi tempi può comportare tempi operativi complessivi lunghi, soprattutto quando si utilizza una strategia di ritardo esponenziale in cui l'intervallo tra i tentativi aumenta rapidamente dopo ogni errore. Se un processo deve soddisfare uno specifico contratto di servizio, il tempo operativo complessivo, inclusi tutti i timeout e i ritardi, deve rientrare nei limiti definiti nel contratto di servizio.
Non implementare strategie di ripetizione eccessivamente aggressive. Si tratta di strategie che hanno intervalli troppo brevi o tentativi troppo frequenti. Possono avere un effetto negativo sulla risorsa o sul servizio di destinazione. Queste strategie potrebbero impedire il ripristino della risorsa o del servizio dallo stato di sovraccarico e continuerà a bloccare o rifiutare le richieste. Questo scenario si traduce in un circolo vizioso, in cui sempre più richieste vengono inviate alla risorsa o al servizio. Di conseguenza, la sua capacità di recupero è ulteriormente ridotta.
Tenere conto del timeout delle operazioni quando si sceglie intervalli di ripetizione dei tentativi per evitare di avviare immediatamente un tentativo successivo( ad esempio, se il periodo di timeout è simile all'intervallo di ripetizione dei tentativi). Valutare anche se è necessario mantenere il periodo totale possibile (il timeout più gli intervalli di ripetizione dei tentativi) al di sotto di un tempo totale specifico. Se un'operazione presenta un timeout insolitamente breve o lungo, il timeout potrebbe influire sulla durata dell'attesa e sulla frequenza con cui ripetere l'operazione.
Usare il tipo dell'eccezione e i dati contenuti o i codici di errore e i messaggi restituiti dal servizio per ottimizzare il numero di tentativi e l'intervallo tra di essi. Ad esempio, alcune eccezioni o codici errore (come il codice HTTP 503, Servizio non disponibile, con un'intestazione Retry-After nella risposta) potrebbero indicare quanto tempo potrebbe durare l'errore o che il servizio non è riuscito e non risponderà ad alcun successivo tentativo.
Evitare antipatterns
Nella maggior parte dei casi, evita le implementazioni che includono livelli duplicati di codice di ripetizione. Evitare progettazioni che includono meccanismi di ripetizione dei tentativi a catena o che implementano nuovi tentativi in ogni fase di un'operazione che implica una gerarchia di richieste, a meno che non si disponga di requisiti specifici che richiedono tale operazione. In queste circostanze eccezionali, utilizza criteri che impediscano un numero eccessivo di tentativi e periodi di ritardo e assicurati di comprenderne le conseguenze. Ad esempio, supponiamo che un componente effettui una richiesta a un altro, che quindi accede al servizio di destinazione. Se imposti un massimale di tre tentativi su entrambe le chiamate, ci sono in totale nove tentativi contro il servizio. Molti servizi e risorse implementano un meccanismo di tentativi integrato. Dovresti indagare su come disabilitare o modificare questi meccanismi se hai bisogno di implementare ritentativi a un livello superiore.
Non implementare mai un meccanismo di tentativi infiniti. Ciò potrebbe impedire il ripristino della risorsa o del servizio da situazioni di sovraccarico e causare limitazioni e connessioni rifiutate per un periodo di tempo più lungo. Usare un numero finito di tentativi o implementare un pattern come Circuit Breaker per consentire il ripristino del servizio.
Non eseguire mai un tentativo immediato più di una volta.
Evitare di usare un intervallo regolare per i tentativi di ripetizione quando si accede a servizi e risorse in Azure, soprattutto quando si ha un numero elevato di tentativi di ripetizione. L'approccio migliore in questo scenario è una strategia esponenziale di arretramento con capabilità di interruzione del circuito.
Impedire a più istanze dello stesso client o a più istanze di client diversi di inviare nuovi tentativi contemporaneamente. Se questo scenario è probabile che si verifichi, introdurre la casualizzazione negli intervalli di ripetizione dei tentativi.
Testa la tua strategia di ripetizione e implementazione
Prova completamente la tua strategia di ripetizione nel più ampio ventaglio possibile di circostanze, soprattutto quando sia l'applicazione stessa che le risorse o i servizi di destinazione utilizzati sono sottoposti a un carico estremo. Per verificare il comportamento durante il test, puoi:
Introduci guasti temporanei e non temporanei nel servizio. Ad esempio, invia richieste non valide o aggiungi codice che rilevi richieste di test e risponda con diversi tipi di errori. Per esempi che usano TestApi, vedere Test di inserimento degli errori con TestApi e Introduzione a TestApi - Parte 5: API di inserimento degli errori per codice gestito.
Crea un modello della risorsa o del servizio che restituisca una serie di errori che il servizio reale potrebbe restituire. Copri tutti i tipi di errori che la tua strategia di ritentativo è progettata per individuare.
Per i servizi personalizzati creati e distribuiti, forza il verificarsi di errori temporanei disabilitando o sovraccaricando temporaneamente il servizio. (Non tentare di sovraccaricare risorse condivise o servizi condivisi in Azure).
Per le API basate su HTTP, prendere in considerazione l'uso di una libreria nei test automatizzati per modificare il risultato delle richieste HTTP, aggiungendo tempi di round trip aggiuntivi o modificando la risposta ,ad esempio il codice di stato HTTP, le intestazioni, il corpo o altri fattori. In questo modo è possibile eseguire test deterministici di un subset delle condizioni di errore, per errori temporanei e altri tipi di errori.
Eseguire test simultanei e fattori di carico elevati per garantire che il meccanismo e la strategia di ripetizione dei tentativi funzionino correttamente in queste condizioni. Questi test aiuteranno anche a garantire che il nuovo tentativo non abbia un effetto negativo sul funzionamento del client o causare contaminazione incrociata tra le richieste.
Gestisci le configurazioni dei criteri di ripetizione
Un criterio di ripetizione è una combinazione di tutti gli elementi della tua strategia di ripetizione. Definisce il meccanismo di rilevamento che determina se è probabile che un errore sia temporaneo, il tipo di intervallo da usare (ad esempio, back-off esponenziale regolare e casualizzazione), i valori effettivi dell'intervallo e il numero di tentativi.
Implementare i ritentativi in molti punti, anche nelle applicazioni più semplici e in ogni livello di applicazioni più complesse. Invece di fissare gli elementi di ogni politica in più posizioni, è consigliabile utilizzare un punto centrale per archiviare tutte le politiche. Ad esempio, archiviare valori come l'intervallo e il numero di tentativi nei file di configurazione dell'applicazione, leggerli in fase di esecuzione e compilare i criteri di ripetizione dei tentativi a livello di codice. In questo modo è più semplice gestire le impostazioni e modificare e ottimizzare i valori per rispondere ai requisiti e agli scenari mutevoli. Tuttavia, progettare il sistema per archiviare i valori anziché rileggere un file di configurazione ogni volta e usare valori predefiniti appropriati se i valori non possono essere ottenuti dalla configurazione.
In un'applicazione Servizi cloud di Azure prendere in considerazione l'archiviazione dei valori usati per compilare i criteri di ripetizione dei tentativi in fase di esecuzione nel file di configurazione del servizio in modo da poterli modificare senza dover riavviare l'applicazione.
Sfrutta le strategie di riprovare predefinite disponibili nelle API client che utilizzi, ma solo quando sono appropriate per il tuo scenario. Queste strategie sono in genere generiche. In alcuni scenari potrebbero essere tutto ciò di cui hai bisogno, ma in altri scenari non offrono la gamma completa di opzioni per soddisfare le tue esigenze specifiche. Per determinare i valori più appropriati, è necessario eseguire dei test per comprendere in che modo le impostazioni influiscono sull'applicazione.
Registra e monitora gli errori temporanei e non temporanei
Nell'ambito della gestione dei tentativi di ripetizione, includi la gestione delle eccezioni e altri strumenti di monitoraggio che registrano i tentativi. Sono previsti errori temporanei occasionali e nuovi tentativi che non indicano un problema. Un numero regolare e crescente di tentativi, tuttavia, è spesso un indicatore di un problema che potrebbe causare un errore o ridurre le prestazioni e la disponibilità dell'applicazione.
Registra gli errori temporanei come voci di avviso anziché come voci di errore in modo che i sistemi di monitoraggio non li rilevino come errori dell'applicazione che potrebbero attivare falsi avvisi.
Valuta la possibilità di archiviare un valore nelle voci di log che indichi se i nuovi tentativi sono causati dalla limitazione del servizio o da altri tipi di errori, come errori di connessione, in modo da poterli differenziare durante l'analisi dei dati. Un aumento del numero di errori di throttling è spesso un indicatore di un difetto di progettazione nell'applicazione o della necessità di passare a un servizio premium che offre hardware dedicato.
Valutare e registrare i tempi complessivi trascorsi per le operazioni che includono un meccanismo di ripetizione dei tentativi. Questa metrica è un buon indicatore dell'effetto complessivo degli errori temporanei nei tempi di risposta dell'utente, nella latenza dei processi e nell'efficienza dei casi d'uso delle applicazioni. Registrare anche il numero di tentativi che si verificano in modo da poter comprendere i fattori che contribuiscono al tempo di risposta.
Prendi in considerazione l'implementazione di un sistema di telemetria e monitoraggio in grado di generare avvisi quando aumenta il numero e il tasso di errori, il numero medio di tentativi o il tempo complessivo trascorso prima che le operazioni abbiano successo.
Gestire le operazioni che falliscono continuamente
Considera come gestire le operazioni che continuano a fallire a ogni tentativo. Situazioni come questa sono inevitabili.
Anche se una strategia di ripetizione dei tentativi definisce il numero massimo di tentativi di ripetizione di un'operazione, non impedisce all'applicazione di ripetere l'operazione con lo stesso numero di tentativi. Ad esempio, se un servizio di elaborazione degli ordini ha un errore irreversibile che lo mette fuori uso in modo permanente, la strategia di ripetizione dei tentativi potrebbe rilevare un timeout di connessione e considerarlo un errore temporaneo. Il codice ritenta l'operazione un numero specificato di volte e quindi rinuncia. Tuttavia, quando un altro cliente effettua un ordine, l'operazione viene tentata di nuovo, anche se avrà esito negativo ogni volta.
Per evitare tentativi ripetuti per le operazioni che falliscono continuamente, è consigliabile implementare il modello Circuit Breaker . Quando si usa questo modello, se il numero di errori all'interno di un intervallo di tempo specificato supera una soglia, le richieste tornano immediatamente al chiamante come errori e non viene eseguito alcun tentativo di accesso alla risorsa o al servizio non riuscito.
L'applicazione può testare periodicamente il servizio, in modo intermittente e con lunghi intervalli tra le richieste, per rilevare quando diventa disponibile. Un intervallo appropriato dipende da fattori quali la criticità dell'operazione e la natura del servizio. Potrebbe durare da pochi minuti a diverse ore. Quando il test ha esito positivo, l'applicazione può riprendere le normali operazioni e passare le richieste al servizio appena ripristinato.
Nel frattempo, potrebbe essere possibile eseguire il fallback a un'altra istanza del servizio (forse in un data center o un'applicazione diversa), usare un servizio simile che offre funzionalità compatibili (forse più semplici) o eseguire alcune operazioni alternative in base alla speranza che il servizio sarà presto disponibile. Ad esempio potrebbe essere opportuno archiviare le richieste del servizio in coda o archivio dati e riprovarle in seguito. In alternativa, potrebbe essere possibile reindirizzare l'utente a un'istanza alternativa dell'applicazione, ridurre le prestazioni dell'applicazione, ma offrire comunque funzionalità accettabili o semplicemente restituire un messaggio all'utente per indicare che l'applicazione non è attualmente disponibile.
Altre considerazioni
Quando decidi i valori per il numero di tentativi e gli intervalli tra i tentativi per un criterio, valuta se l'operazione sul servizio o sulla risorsa fa parte di un'operazione a lunga esecuzione o a più passaggi. Potrebbe essere difficile o costoso compensare tutti gli altri passaggi operativi che hanno già avuto esito positivo quando si verifica un errore. In questo caso, un intervallo molto lungo e un numero elevato di tentativi potrebbe essere accettabile purché tale strategia non blocchi altre operazioni mantenendo o bloccando risorse scarse.
Valuta se riprovare la stessa operazione potrebbe causare incoerenze nei dati. Se alcune parti di un processo a più fasi vengono ripetute e le operazioni non sono idempotenti, potrebbero verificarsi incoerenze. Ad esempio, se un'operazione che incrementa un valore viene ripetuta, produce un risultato non valido. La ripetizione di un'operazione che invia un messaggio a una coda potrebbe causare un'incoerenza nel consumatore di messaggi se il consumatore non riesce a rilevare messaggi duplicati. Per evitare questi scenari, progettare ogni passaggio come operazione idempotente. Per altre informazioni, vedere modelli di Idempotenza.
Considera l'ambito delle operazioni tentate nuovamente. Ad esempio, potrebbe essere più semplice implementare il codice di ripetizione a un livello che comprenda diverse operazioni e riprovarle tutte se una fallisce. Tuttavia, ciò potrebbe causare problemi di idempotenza o operazioni di rollback non necessarie.
Se si sceglie un ambito di ripetizione dei tentativi che include diverse operazioni, tenere conto della latenza totale di tutte quando si determinano gli intervalli di ripetizione dei tentativi, quando si monitorano i tempi trascorsi dell'operazione e prima di generare avvisi per gli errori.
Valutare il modo in cui la strategia di ripetizione dei tentativi potrebbe influire sui vicini e sugli altri tenant in un'applicazione condivisa e quando si usano risorse e servizi condivisi. I criteri di ripetizione aggressivi possono causare un numero crescente di errori temporanei per questi altri utenti e per le applicazioni che condividono le risorse e i servizi. Analogamente, l'applicazione potrebbe essere interessata dai criteri di ripetizione dei tentativi implementati da altri utenti delle risorse e dei servizi. Per le applicazioni critiche per l'azienda, è possibile usare servizi Premium che non sono condivisi. In questo modo è possibile controllare il carico e la conseguente limitazione di queste risorse e servizi, che possono contribuire a giustificare il costo aggiuntivo.