Condividi tramite


Indicazioni sulla ripetizione dei tentativi per i servizi di Azure

La maggior parte dei servizi di Azure e degli SDK client include un meccanismo di ripetizione dei tentativi. Ogni servizio, tuttavia, presenta caratteristiche e requisiti diversi e, quindi, ogni meccanismo di ripetizione dei tentativi è ottimizzato per il servizio specifico in cui è incorporato. Questo articolo riepiloga le caratteristiche dei meccanismi di ripetizione dei tentativi relativi alla maggior parte dei servizi di Azure e include utili informazioni per usare, adattare o estendere il meccanismo di ripetizione dei tentativi per ogni servizio.

Per indicazioni generali sulla gestione degli errori temporanei e sulla ripetizione dei tentativi di eseguire connessioni e operazioni su servizi e risorse, vedere Indicazioni generali per la ripetizione di tentativi.

La tabella seguente riepiloga le caratteristiche dei meccanismi di ripetizione dei tentativi associati ai servizi di Azure descritti in questo articolo.

Servizio Funzionalità per la ripetizione di tentativi Configurazione dei criteri Scope Funzionalità di telemetria
Microsoft Entra ID Native nella libreria MSAL Incorporata nella libreria MSAL Internal None
Azure Cosmos DB Native nel servizio Non configurabili Generale TraceSource
Data Lake Store Native nel client Non configurabili Singole operazioni None
Hub eventi Native nel client Programmatica Client None
Hub IoT Native nell'SDK client Programmatica Client None
Cache Redis di Azure Native nel client Programmatica Client TextWriter
Ricerca Native nel client Programmatica Client Traccia eventi per Windows (ETW) o personalizzata
Bus di servizio Native nel client Programmatica Gestore dello spazio dei nomi, factory di messaggistica e client ETW
Service Fabric Native nel client Programmatica Client None
Database SQL con ADO.NET Polly Dichiarativa e a livello di codice Singole istruzioni o blocchi di codice Personalizzazione
Database SQL con Entity Framework Native nel client Programmatica Globale per AppDomain None
Database SQL con Entity Framework Core Native nel client Programmatica Globale per AppDomain None
Storage Native nel client Programmatica Client e singole operazioni TraceSource

Nota

Per la maggior parte dei meccanismi di ripetizione dei tentativi predefiniti di Azure, non è attualmente possibile applicare criteri di ripetizione differenti per diversi tipi di errori o eccezioni. È necessario configurare un criterio che fornisca prestazioni e disponibilità medie ottimali. I criteri possono essere successivamente ottimizzati analizzando i file di log per determinare i tipi di errori temporanei che si sono verificati.

Microsoft Entra ID

Microsoft Entra ID è una soluzione cloud di gestione di accessi e identità completa e altamente disponibile, in grado di combinare servizi directory di base, governance avanzata delle identità, sicurezza e gestione degli accessi alle applicazioni. Microsoft Entra ID offre inoltre agli sviluppatori una piattaforma di gestione delle identità per consentire il controllo dell'accesso alle applicazioni in base a regole e criteri centralizzati.

Nota

Per informazioni sulla ripetizione dei tentativi negli endpoint dell'identità del servizio gestita, vedere Come usare un'identità del servizio gestita di una macchina virtuale di Azure per l'acquisizione di token.

Meccanismo di ripetizione dei tentativi

In Microsoft Authentication Library (MSAL) è previsto un meccanismo di ripetizione dei tentativi predefinito per Microsoft Entra ID. Per evitare blocchi imprevisti, è consigliabile che le librerie di terze parti e il codice dell'applicazione non ripetano i tentativi di connessione non riusciti, ma consentano a MSAL di gestire i tentativi.

Linee guida sull'uso dei criteri di ripetizione dei tentativi

Quando si utilizza Microsoft Entra ID, tenere presenti le linee guida seguenti:

  • Quando possibile, usare la libreria MSAL e il supporto predefinito per le ripetizioni dei tentativi.
  • Se si usa l'API REST per Microsoft Entra ID, ripetere l'operazione se il codice di risultato è 429 (Troppe richieste) oppure un errore compreso nell'intervallo 5xx. Non ripetere nuovi tentativi per altri tipi di errore.
  • Per gli errori 429, riprovare solo dopo il tempo indicato nell'intestazione Retry-After.
  • Per gli errori 5xx, usare il backoff esponenziale, con il primo tentativo effettuato almeno 5 secondi dopo la risposta.
  • Non riprovare in caso di errori diversi da 429 e 5xx.

Passaggi successivi

Azure Cosmos DB

Cosmos DB di Azure è un database multi-modello completamente gestito che supporta i dati JSON senza schema. Offre prestazioni affidabili e configurabili, consente l'elaborazione transazionale JavaScript nativa e, grazie alla scalabilità elastica, è ottimizzato per il cloud.

Meccanismo di ripetizione dei tentativi

Gli SDK Cosmos DB di Azure riprovano automaticamente in determinate condizioni di errore e le applicazioni utente sono incoraggiate ad avere criteri di ripetizione dei tentativi. Consultare la guida alla progettazione di applicazioni resilienti con gli SKD Cosmos DB di Azure per un elenco completo delle condizioni di errore e quando riprovare.

Telemetria

A seconda del linguaggio dell'applicazione, la diagnostica e i dati di telemetria vengono esposti come log o proprietà alzate di livello nelle risposte dell'operazione. Per maggiori informazioni, consultare la sezione "Acquisire la diagnostica" in Cosmos DB C# SDK di Azure e Cosmos DB Java SDK di Azure.

Data Lake Store

Data Lake Storage Gen2 usa Archiviazione di Azure come base per la compilazione di Enterprise Data Lake (EDL) in Azure. Data Lake Storage Gen2 consente di gestire facilmente enormi quantità di dati.

La libreria client File di archiviazione di Azure Data Lake include tutte le funzionalità necessarie a sviluppatori, data scientist e analisti per archiviare più facilmente dati di tutte le dimensioni, forme e velocità e svolgere qualsiasi tipo di elaborazione e analisi su più piattaforme e linguaggi.

Meccanismo di ripetizione dei tentativi

DataLakeServiceClient consente di modificare le risorse e i file system del servizio Azure Data Lake. L'account di archiviazione rappresenta lo spazio dei nomi di primo livello per il servizio Data Lake. Quando si crea il client, è possibile fornire le opzioni di configurazione client per la connessione al servizio Azure Data Lake (DataLakeClientOptions). DataLakeClientOptions include una proprietà Retry (ereditata da Azure.Core.ClientOptions) che può essere configurata (classe RetryOptions).

Telemetria

Il monitoraggio dell'uso e delle prestazioni di Archiviazione di Azure è una parte importante dell'operazionalizzazione del servizio. Gli esempi includono operazioni frequenti, operazioni con latenza elevata o operazioni che causano la limitazione lato servizio.

Tutti i dati di telemetria per l'account di archiviazione sono disponibili tramite log di Archiviazione di Azure in Monitoraggio di Azure. Questa funzionalità integra l'account di archiviazione con Analisi dei log e Hub eventi, consentendo anche di archiviare i log in un altro account di archiviazione. Per visualizzare l'elenco completo dei log delle metriche e delle risorse e dello schema associato, consultare la sezione Archiviazione di Azure riferimento ai dati di monitoraggio.

Hub eventi

Hub eventi di Azure è un servizio di inserimento di dati di telemetria con iperscalabilità che raccoglie, trasforma e archivia milioni di eventi.

Meccanismo di ripetizione dei tentativi

Il comportamento di ripetizione dei tentativi nella libreria client dell'Hub eventi di Azure è controllato dalla proprietà RetryPolicy nella classe EventHubClient. I criteri predefiniti eseguono nuovi tentativi con backoff esponenziale quando Hub eventi di Azure restituisce EventHubsException o OperationCanceledException temporanei. I criteri di ripetizione predefiniti per Hub eventi prevedono un massimo di 9 tentativi con un intervallo di backoff esponenziale di 30 secondi al massimo.

Esempio

EventHubClient client = EventHubClient.CreateWithManagedIdentity(new Uri("sb://full_namespace_url", "entity_path");
client.RetryPolicy = RetryPolicy.Default;

Passaggi successivi

Libreria client Hub eventi di Azure per .NET

Hub IoT

Hub IoT di Azure è un servizio per la connessione, il monitoraggio e la gestione di dispositivi per lo sviluppo di applicazioni Internet delle cose (IoT).

Meccanismo di ripetizione dei tentativi

Azure IoT SDK per dispositivi è in grado di rilevare errori nella rete, nel protocollo o nell'applicazione. In base al tipo di errore, l'SDK verifica se è necessario eseguire un nuovo tentativo. Se l'errore è reversibile, l'SDK avvia un nuovo tentativo usando i criteri di ripetizione configurati.

I criteri di ripetizione predefiniti prevedono il backoff esponenziale con instabilità casuale, ma possono essere configurati.

Configurazione dei criteri

La configurazione dei criteri varia a seconda del linguaggio. Per maggiori dettagli, vedere la configurazione dei criteri di ripetizione per l'hub IoT.

Passaggi successivi

Cache Redis di Azure

La cache di Azure per Redis è un servizio cache a bassa latenza e di rapido accesso ai dati basato sulla nota Cache Redis open source. È sicura, gestita da Microsoft e accessibile da qualsiasi applicazione in Azure.

Le indicazioni fornite in questa sezione presuppongono che si usi il client StackExchange.Redis per accedere alla cache. Nel sito Web di Redisè disponibile un elenco di altri client idonei, a cui possono essere associati vari meccanismi di ripetizione dei tentativi.

Il client StackExchange.Redis usa il multiplexing tramite un'unica connessione. È consigliabile quindi creare un'istanza del client all'avvio dell'applicazione e usarla per tutte le operazioni eseguite sulla cache. In questo modo, la connessione alla cache viene eseguita una sola volta e tutte le indicazioni fornite in questa sezione fanno riferimento ai criteri di ripetizione dei tentativi definiti per la connessione iniziale e non per ogni operazione che accede alla cache.

Meccanismo di ripetizione dei tentativi

Il client StackExchange.Redis usa una classe di gestione della connessione configurata tramite un set di opzioni, che include:

  • ConnectRetry. Il numero di volte in cui una connessione non riuscita per la cache verrà ritentata.
  • ReconnectRetryPolicy. La strategia di ripetizione dei tentativi da usare.
  • ConnectTimeout. Il tempo di attesa massimo in millisecondi.

Configurazione dei criteri

I criteri di ripetizione dei tentativi vengono configurati a livello di codice impostando le opzioni per il client prima di connettersi alla cache. Questa operazione può essere eseguita creando un'istanza della classe ConfigurationOptions, popolandone le proprietà e passandola al metodo Connect.

Le classi incorporate supportano i ritardi lineari, ovvero il tempo d'intervallo costante, e i backoff esponenziali con intervalli di ripetizione dei tentativi casuali. È anche possibile creare un criterio di ripetizione dei tentativi personalizzato implementando l'interfaccia IReconnectRetryPolicy.

L'esempio seguente consente di configurare una strategia di ripetizione dei tentativi con backoff esponenziale.

var deltaBackOffInMilliseconds = TimeSpan.FromSeconds(5).TotalMilliseconds;
var maxDeltaBackOffInMilliseconds = TimeSpan.FromSeconds(20).TotalMilliseconds;
var options = new ConfigurationOptions
{
    EndPoints = {"localhost"},
    ConnectRetry = 3,
    ReconnectRetryPolicy = new ExponentialRetry(deltaBackOffInMilliseconds, maxDeltaBackOffInMilliseconds),
    ConnectTimeout = 2000
};
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);

In alternativa, è possibile specificare le opzioni sotto forma di stringa, per poi passarla al metodo Connect . La proprietà ReconnectRetryPolicy non può essere impostata in questo modo, ma solo tramite codice.

var options = "localhost,connectRetry=3,connectTimeout=2000";
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);

È anche possibile specificare le opzioni direttamente durante la connessione alla cache.

var conn = ConnectionMultiplexer.Connect("redis0:6380,redis1:6380,connectRetry=3");

Per altre informazioni, vedere Configurazione di Stack Exchange Redis nella documentazione di StackExchange.Redis.

La tabella seguente mostra le impostazioni predefinite per i criteri di ripetizione dei tentativi incorporati.

Contesto Impostazione Valore predefinito
(v 1.2.2)
significato
Opzioni configurazione ConnectRetry

ConnectTimeout

SyncTimeout

ReconnectRetryPolicy
3

Massimo 5000 ms più SyncTimeout
1000

LinearRetry 5.000 ms
Numero di nuovi tentativi di connessione durante l'operazione di connessione iniziale.
Timeout (ms) per operazioni di connessione. Non un intervallo tra i tentativi.
Tempo (ms) concesso per consentire operazioni sincrone.

Ripetizione dei tentativi ogni 5.000 ms.

Nota

Per le operazioni sincrone, è possibile aggiungere SyncTimeout alla latenza end-to-end, ma impostare un valore troppo basso può causare timeout eccessivi. Per maggiori informazioni, consultare la sezione Risoluzione dei problemi di cache di Azure per Redis. In generale, evitare di usare operazioni sincrone, usare invece operazioni asincrone. Per altre informazioni, vedere Pipeline e multiplexer.

Linee guida sull'uso dei criteri di ripetizione dei tentativi

Quando si usa la cache di Azure per Redis, tenere presente le linee guida seguenti:

  • Il client StackExchange Redis gestisce autonomamente i propri tentativi, ma solo se viene stabilita una connessione alla cache al primo avvio dell'applicazione. È possibile configurare il timeout di connessione, il numero di ripetizione di tentativi e l'intervallo di tempo tra i tentativi per stabilire la connessione, ma i criteri di ripetizione non si applicano alle operazioni eseguite sulla cache.
  • Anziché ricorrere a un numero elevato di tentativi, valutare la possibilità di eseguire il fallback accedendo alla sorgente originale dei dati.

Telemetria

È possibile raccogliere informazioni sulle connessioni, ma su non altre operazioni, usando un TextWriter.

var writer = new StringWriter();
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);

Seguito è riportato un esempio di output generato.

localhost:6379,connectTimeout=2000,connectRetry=3
1 unique nodes specified
Requesting tie-break from localhost:6379 > __Booksleeve_TieBreak...
Allowing endpoints 00:00:02 to respond...
localhost:6379 faulted: SocketFailure on PING
localhost:6379 failed to nominate (Faulted)
> UnableToResolvePhysicalConnection on GET
No masters detected
localhost:6379: Standalone v2.0.0, master; keep-alive: 00:01:00; int: Connecting; sub: Connecting; not in use: DidNotRespond
localhost:6379: int ops=0, qu=0, qs=0, qc=1, wr=0, sync=1, socks=2; sub ops=0, qu=0, qs=0, qc=0, wr=0, socks=2
Circular op-count snapshot; int: 0 (0.00 ops/s; spans 10s); sub: 0 (0.00 ops/s; spans 10s)
Sync timeouts: 0; fire and forget: 0; last heartbeat: -1s ago
resetting failing connections to retry...
retrying; attempts left: 2...
...

Esempi

L'esempio di codice seguente consente di configurare un intervallo costante, ovvero lineare, tra le ripetizioni di tentativi durante l'inizializzazione del client StackExchange.Redis. Questo esempio illustra come impostare la configurazione usando un'istanza ConfigurationOptions.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StackExchange.Redis;

namespace RetryCodeSamples
{
    class CacheRedisCodeSamples
    {
        public async static Task Samples()
        {
            var writer = new StringWriter();
            {
                try
                {
                    var retryTimeInMilliseconds = TimeSpan.FromSeconds(4).TotalMilliseconds; // delay between retries

                    // Using object-based configuration.
                    var options = new ConfigurationOptions
                                        {
                                            EndPoints = { "localhost" },
                                            ConnectRetry = 3,
                                            ReconnectRetryPolicy = new LinearRetry(retryTimeInMilliseconds)
                                        };
                    ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);

                    // Store a reference to the multiplexer for use in the application.
                }
                catch
                {
                    Console.WriteLine(writer.ToString());
                    throw;
                }
            }
        }
    }
}

L'esempio successivo imposta la configurazione specificando le opzioni sotto forma di stringa. Il timeout di connessione è l'intervallo di tempo massimo di attesa per la connessione alla cache, non l'intervallo tra i tentativi. La proprietà ReconnectRetryPolicy può essere impostata solo dal codice.

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StackExchange.Redis;

namespace RetryCodeSamples
{
    class CacheRedisCodeSamples
    {
        public async static Task Samples()
        {
            var writer = new StringWriter();
            {
                try
                {
                    // Using string-based configuration.
                    var options = "localhost,connectRetry=3,connectTimeout=2000";
                    ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);

                    // Store a reference to the multiplexer for use in the application.
                }
                catch
                {
                    Console.WriteLine(writer.ToString());
                    throw;
                }
            }
        }
    }
}

Per altri esempi, vedere la sezione relativa alla configurazione sul sito Web di progetto.

Passaggi successivi

Lo strumento Ricerca di Azure può essere usato per aggiungere sofisticate e avanzate funzionalità di ricerca in un sito Web o un'applicazione, ottimizzare i risultati di ricerca in modo semplice e rapido e creare avanzati modelli di classificazione.

Meccanismo di ripetizione dei tentativi

Azure SDK per .NET include una libreria client Azure.Search.Documents del team di Azure SDK equivalente funzionalmente alla libreria client precedente, Microsoft.Azure.Search.

Il comportamento di ripetizione in Microsoft.Azure.Search è controllato dal metodo SetRetryPolicy nelle classi SearchServiceClient e SearchIndexClient. I criteri predefiniti eseguono nuovi tentativi con backoff esponenziale quando Ricerca di Azure restituisce una risposta 5xx o 408 (Timeout della richiesta).

Il comportamento di ripetizione dei tentativi in Azure.Search.Documents è controllato da SearchClientOptions (fa parte del costruttore SearchClient) nella proprietà Retry, che appartiene alla classe Azure.Core.RetryOptions(dove sono disponibili tutte le configurazioni).

Telemetria

Tracciare con ETW o registrando un provider di traccia personalizzato. Per altre informazioni, consultare la documentazione di AutoRest.

Bus di servizio

Il bus di servizio è una piattaforma di messaggistica basata sul cloud che offre una funzione di scambio dei messaggi di tipo "loosely coupled" con alti livelli di scalabilità e resilienza per i componenti di un'applicazione (ospitata nel cloud o in locale).

Meccanismo di ripetizione dei tentativi

Lo spazio dei nomi e alcuni dei dettagli di configurazione dipendono dal pacchetto SDK client del bus di servizio usato:

Pacchetto Descrizione Spazio dei nomi
Azure.Messaging.ServiceBus Libreria client del bus di servizio di Azure per .NET Azure.Messaging.ServiceBus
WindowsAzure.ServiceBus Questo pacchetto è la libreria client del bus di servizio precedente. Richiede .NET Framework 4.5.2. Microsoft.Azure.ServiceBus

Linee guida sull'uso dei criteri di ripetizione dei tentativi

La ServiceBusRetryOptions proprietà specifica le opzioni di ripetizione dei tentativi per l'ServiceBusClientoggetto:

Impostazione Default value significato
CustomRetryPolicy Criteri di ripetizione dei tentativi personalizzati da usare al posto dei singoli valori di opzione.
Ritardo 0.8 secondi Ritardo tra i tentativi di ripetizione per un approccio fisso o il ritardo su cui basare i calcoli per un approccio basato sul backoff.
MaxDelay 60 secondi Ritardo massimo permissibile tra i tentativi.
MaxRetries 3 Numero massimo di tentativi prima di considerare l'operazione associata non riuscita.
Modalità Esponenziale Approccio da usare per calcolare i ritardi di ripetizione dei tentativi.
TryTimeout 60 secondi Durata massima di attesa del completamento di un singolo tentativo, sia che si tratti del tentativo iniziale o di un nuovo tentativo.

Impostare la Mode proprietà per configurare ServiceBusRetryMode con uno di questi valori:

Proprietà valore Descrizione
Esponenziale 1 I tentativi di ripetizione ritarderanno in base a una strategia di backoff, in cui ogni tentativo aumenterà la durata di attesa prima di riprovare.
Fisso 0 I tentativi di ripetizione vengono eseguiti a intervalli fissi; ogni ritardo è una durata coerente.

Esempio:

using Azure.Identity;
using Azure.Messaging.ServiceBus;

string namespace = "<namespace>";
string queueName = "<queue_name>";

// Because ServiceBusClient implements IAsyncDisposable, we'll create it
// with "await using" so that it is automatically disposed for us.
var options = new ServiceBusClientOptions();
options.RetryOptions = new ServiceBusRetryOptions
{
    Delay = TimeSpan.FromSeconds(10),
    MaxDelay = TimeSpan.FromSeconds(30),
    Mode = ServiceBusRetryMode.Exponential,
    MaxRetries = 3,
};
await using var client = new ServiceBusClient(namespace, new DefaultAzureCredential(), options);

Telemetria

Bus di servizio raccoglie gli stessi tipi di dati di monitoraggio delle altre risorse di Azure. È possibile usare Monitorare bus di servizio di Azure usando Monitoraggio di Azure.

Sono disponibili anche diverse opzioni per l'invio di dati di telemetria con le librerie client .NET bus di servizio.

Esempio

Nell'esempio di codice riportato di seguito viene illustrato come utilizzare il pacchetto Azure.Messaging.ServiceBus per.

  • Impostare i criteri di ripetizione dei tentativi per ServiceBusClient usando un nuovo ServiceBusClientOptions.
  • Creare un nuovo messaggio con una nuova istanza di ServiceBusMessage.
  • Inviare un messaggio al bus di servizio usando il metodo ServiceBusSender.SendMessageAsync(message).
  • Ricevere utilizzando ServiceBusReceiver, rappresentato come oggetti ServiceBusReceivedMessage.
using Azure.Identity;
using Azure.Messaging.ServiceBus;

string namespace = "<namespace>";
string queueName = "queue1";

// Because ServiceBusClient implements IAsyncDisposable, we'll create it 
// with "await using" so that it is automatically disposed for us.
var options = new ServiceBusClientOptions();
options.RetryOptions = new ServiceBusRetryOptions
{
    Delay = TimeSpan.FromSeconds(10),
    MaxDelay = TimeSpan.FromSeconds(30),
    Mode = ServiceBusRetryMode.Exponential,
    MaxRetries = 3,
};
await using var client = new ServiceBusClient(namespace, new DefaultAzureCredential(), options);

// The sender is responsible for publishing messages to the queue.
ServiceBusSender sender = client.CreateSender(queueName);
ServiceBusMessage message = new ServiceBusMessage("Hello world!");

await sender.SendMessageAsync(message);

// The receiver is responsible for reading messages from the queue.
ServiceBusReceiver receiver = client.CreateReceiver(queueName);
ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();

string body = receivedMessage.Body.ToString();
Console.WriteLine(body);

Passaggi successivi

Service Fabric

La distribuzione di servizi affidabili in un cluster di Service Fabric protegge dalla maggior parte degli errori temporanei potenziali descritti in questo articolo. Tuttavia, alcuni errori temporanei sono comunque possibili. Ad esempio, il servizio di denominazione potrebbe essere all'interno di una modifica di routing quando rileva una richiesta, provocando la generazione di un'eccezione. Se la stessa richiesta arriva 100 millisecondi dopo, verrà probabilmente completata.

Service Fabric gestisce internamente questo tipo di errori temporanei. È possibile configurare alcune impostazioni tramite la classe OperationRetrySettings durante la configurazione dei servizi. Il seguente codice illustra un esempio. Nella maggior parte dei casi, ciò non dovrebbe essere necessario e le impostazioni predefinite sono adeguate.

FabricTransportRemotingSettings transportSettings = new FabricTransportRemotingSettings
{
    OperationTimeout = TimeSpan.FromSeconds(30)
};

var retrySettings = new OperationRetrySettings(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(1), 5);

var clientFactory = new FabricTransportServiceRemotingClientFactory(transportSettings);

var serviceProxyFactory = new ServiceProxyFactory((c) => clientFactory, retrySettings);

var client = serviceProxyFactory.CreateServiceProxy<ISomeService>(
    new Uri("fabric:/SomeApp/SomeStatefulReliableService"),
    new ServicePartitionKey(0));

Passaggi successivi

Database SQL con ADO.NET

Il database SQL, in questo caso, è un database SQL ospitato, di varie dimensioni, disponibile come servizio standard (condiviso) o premium (non condiviso).

Meccanismo di ripetizione dei tentativi

Il database SQL non offre il supporto incorporato per la ripetizione dei tentativi quando si accede ad esso con ADO.NET. Per determinare il motivo per cui una richiesta ha avuto esito negativo, è possibile usare i codici restituiti dalle richieste. Per altre informazioni sulla limitazione delle richieste del database SQL, vedere Limiti delle risorse del database SQL di Azure. Per un elenco dei codici di errore pertinenti, vedere Codici di errore SQL per le applicazioni client del database SQL.

È possibile usare la libreria Polly per implementare la ripetizione di tentativi per il database SQL. Per maggiori informazioni, consultare la sezione Blocco di applicazioni per la gestione degli errori temporanei.

Linee guida sull'uso dei criteri di ripetizione dei tentativi

Quando si accede al database SQL con ADO.NET, tenere presente le linee guida seguenti:

  • Scegliere il tipo di servizio appropriato (condiviso o premium). Un'istanza condivisa può subire limitazioni o ritardi di connessione maggiori rispetto alla media perché può essere usata da altri tenant del server condiviso. Se sono necessarie prestazioni più prevedibili o affidabili operazioni di bassa latenza, valutare la possibilità di scegliere il tipo servizio premium.
  • Assicurarsi di eseguire i nuovi tentativi al livello o nell'ambito appropriato per evitare operazioni non idempotenti che possono causare incoerenze nei dati. In teoria, tutte le operazioni dovrebbero essere idempotenti in modo da poter essere ripetute senza causare incoerenze. Se questo non avviene, i nuovi tentativi devono essere eseguiti a un livello o in un ambito che consenta l'annullamento di tutte le modifiche correlate in caso di esito negativo di un'operazione, ad esempio un ambito transazionale. Per altre informazioni, vedere l'articolo sul livello di accesso ai dati di Cloud Service Fundamentals e la gestione degli errori temporanei.
  • Non è consigliabile una strategia basata su intervalli fissi per il database SQL di Azure, se non negli scenari interattivi in cui vengono eseguiti solo alcuni tentativi a intervalli molto brevi. In alternativa, valutare la possibilità di usare una strategia di backoff esponenziale per la maggior parte degli scenari.
  • Quando si definiscono le connessioni, scegliere un valore appropriato per i timeout di connessione e dei comandi. Un timeout troppo breve può comportare errori di connessione prematuri quando il database è occupato, mentre un timeout troppo lungo può impedire che la logica di ripetizione dei tentativi funzioni correttamente, poiché l'intervallo di attesa prima che venga rilevata una connessione non riuscita è troppo lungo. Il valore di timeout è un componente della latenza end-to-end; per ogni nuovo tentativo, viene aggiunto all'intervallo tra i tentativi specificato nei criteri di ripetizione dei tentativi.
  • Chiudere la connessione dopo qualche tentativo, anche se si usa una logica di ripetizione dei tentativi con backoff esponenziale, e ripetere l'operazione su una nuova connessione. Se si ripete più volte la stessa operazione su un'unica connessione, infatti, è possibile che si verifichino problemi di connessione. Per altre informazioni su questa tecnica, vedere l'articolo sul livello di accesso ai dati di Cloud Service Fundamentals e la gestione degli errori temporanei.
  • Se si usa il pool di connessioni (impostazione predefinita), è probabile che venga scelta la stessa connessione, anche dopo aver chiuso e riaperto una connessione. Se si verifica questo problema, è possibile risolverlo chiamando il metodo ClearPool della classe SqlConnection per contrassegnare la connessione come non riutilizzabile. Questo metodo, tuttavia, deve essere adottato solo dopo vari tentativi di connessione non riusciti e solo quando è presente la classe di errori temporanei, come i timeout SQL (codice di errore -2), specifica delle connessioni difettose.
  • Se il codice di accesso ai dati usa transazioni avviate come istanze TransactionScope , la logica di ripetizione dei tentativi deve riaprire la connessione e avviare un nuovo ambito della transazione. Per questo motivo, il blocco di codice non irreversibile deve interessare l'intero ambito della transazione.

È consigliabile iniziare le operazioni di ripetizione dei tentativi usando le impostazioni seguenti. Queste impostazioni sono di utilizzo generico ed è quindi necessario monitorare le operazioni e personalizzare i valori in base allo scenario.

Contesto Latenza massima destinazione
esempio E2E
Strategia di ripetizione dei tentativi Impostazioni Valori Funzionamento
Interattivo, interfaccia utente
o in primo piano
2 secondi FixedInterval Conteggio tentativi
Intervallo tentativi
Primo tentativo rapido
3
500 ms
true
Tentativo di 1 - intervallo di 0 sec
Tentativo 2 - intervallo di 500 ms
Tentativo 3 - intervallo di 500 ms
Background
o batch
30 Secondi ExponentialBackoff Conteggio tentativi
Interruzione temporanea minima
Interruzione temporanea massima
Interruzione temporanea delta
Primo tentativo rapido
5
0 secondi
60 secondi
2 secondi
false
Tentativo di 1 - intervallo di 0 sec
Tentativo 2 - intervallo di ~2 sec
Tentativo 3 - intervallo di ~6 sec
Tentativo 4 - intervallo di ~14 sec
Tentativo 5 - intervallo di 30 sec

Nota

Gli obiettivi di latenza end-to-end presuppongono il timeout predefinito per le connessioni al servizio. Se si specifica un timeout di connessione più lungo, la latenza end-to-end verrà estesa di questo intervallo di tempo aggiuntivo per ogni nuovo tentativo.

Esempi

Questa sezione illustra come usare Polly per accedere al database SQL di Azure usando un set di criteri di ripetizione dei tentativi configurato nella classe Policy.

Il codice seguente illustra un metodo di estensione nella classe SqlCommand che richiama ExecuteAsync con backoff esponenziale.

public async static Task<SqlDataReader> ExecuteReaderWithRetryAsync(this SqlCommand command)
{
    GuardConnectionIsNotNull(command);

    var policy = Policy.Handle<Exception>().WaitAndRetryAsync(
        retryCount: 3, // Retry 3 times
        sleepDurationProvider: attempt => TimeSpan.FromMilliseconds(200 * Math.Pow(2, attempt - 1)), // Exponential backoff based on an initial 200 ms delay.
        onRetry: (exception, attempt) =>
        {
            // Capture some information for logging/telemetry.
            logger.LogWarn($"ExecuteReaderWithRetryAsync: Retry {attempt} due to {exception}.");
        });

    // Retry the following call according to the policy.
    await policy.ExecuteAsync<SqlDataReader>(async token =>
    {
        // This code is executed within the Policy

        if (conn.State != System.Data.ConnectionState.Open) await conn.OpenAsync(token);
        return await command.ExecuteReaderAsync(System.Data.CommandBehavior.Default, token);

    }, cancellationToken);
}

Questo metodo di estensione asincrona può essere usato come indicato di seguito.

var sqlCommand = sqlConnection.CreateCommand();
sqlCommand.CommandText = "[some query]";

using (var reader = await sqlCommand.ExecuteReaderWithRetryAsync())
{
    // Do something with the values
}

Passaggi successivi

Database SQL con Entity Framework 6

Il database SQL, in questo caso, è un database SQL ospitato, di varie dimensioni, disponibile come servizio standard (condiviso) o premium (non condiviso). Entity Framework, invece, è un mapper relazionale a oggetti che consente agli sviluppatori .NET di usare dati relazionali mediante oggetti specifici di dominio. Elimina la necessità di gran parte del codice di accesso ai dati che in genere gli sviluppatori devono scrivere.

Meccanismo di ripetizione dei tentativi

Quando si accede al database SQL con Entity Framework 6.0 o versione superiore, il supporto per la ripetizione di tentativi viene fornito attraverso un meccanismo denominato resilienza delle connessioni / logica di ripetizione dei tentativi. Di seguiti sono illustrate le caratteristiche principali del meccanismo di ripetizione dei tentativi:

  • L'astrazione primaria è l'interfaccia IDbExecutionStrategy . Questa interfaccia:
    • Definisce i metodi Execute sincroni e asincroni.
    • Definisce le classi che possono essere usate direttamente o configurate in un contesto di database come strategia predefinita, quindi mappate a un nome di provider o a un nome di provider e un nome di server. Se configurate in un contesto, i nuovi tentativi vengono eseguiti a livello di singole operazioni di database, che possono essere molteplici per una determinata operazione di contesto.
    • Definisce quando tentare di eseguire nuovamente una connessione non riuscita e in che modo.
  • Include diverse implementazioni incorporate dell'interfaccia IDbExecutionStrategy :
    • Predefinita: nessun nuovo tentativo.
    • Predefinita per il database SQL (automatica): nessun nuovo tentativo, ma controlla le eccezioni e ne esegue il wrapping con il suggerimento di usare la strategia relativa al database SQL.
    • Predefinita per il database SQL: esponenziale (ereditata dalla classe di base), combinata con la logica di rilevamento del database SQL.
  • Implementa una strategia di backoff esponenziale che include la sequenza casuale.
  • Le classi di ripetizione dei tentativi predefinite non sono classi con stato di tipo thread-safe. Possono comunque essere riusate dopo il completamento dell'operazione corrente.
  • Se viene superato il numero di tentativi specificato, i risultati vengono inclusi in una nuova eccezione e l'eccezione corrente non viene visualizzata.

Configurazione dei criteri

Quando si accede al database SQL con Entity Framework 6.0, o versioni successive, è già disponibile il supporto per la ripetizione di tentativi. I criteri di ripetizione dei tentativi sono configurati a livello di codice. La configurazione non può essere modificata a livello di singola operazione.

Quando si configura una strategia di contesto come impostazione predefinita, è necessario specificare anche una funzione che consente di creare una nuova strategia su richiesta. Il codice seguente mostra come creare una classe di configurazione di nuovi tentativi che estende la classe di base DbConfiguration .

public class BloggingContextConfiguration : DbConfiguration
{
  public BlogConfiguration()
  {
    // Set up the execution strategy for SQL Database (exponential) with 5 retries and 4 sec delay
    this.SetExecutionStrategy(
         "System.Data.SqlClient", () => new SqlAzureExecutionStrategy(5, TimeSpan.FromSeconds(4)));
  }
}

È quindi possibile impostarla come strategia di ripetizione dei tentativi predefinita per tutte le operazioni usando il metodo SetConfiguration dell'istanza DbConfiguration all'avvio dell'applicazione. Per impostazione predefinita, Entity Framework rileverà e userà automaticamente questa classe di configurazione.

DbConfiguration.SetConfiguration(new BloggingContextConfiguration());

È possibile specificare la classe di configurazione di nuovi tentativi per un contesto specifico annotando la classe del contesto con un attributo DbConfigurationType . Tuttavia, se è presente una sola classe di configurazione, Entity Framework la userà anche senza dover annotare il contesto.

[DbConfigurationType(typeof(BloggingContextConfiguration))]
public class BloggingContext : DbContext

Se per determinate operazioni è necessario usare strategie di ripetizione dei tentativi diverse o si disabilita la ripetizione dei tentativi, è possibile creare una classe di configurazione che consente di sospendere o cambiare strategie impostando un flag in CallContext. Questo flag può essere usato dalla classe di configurazione per cambiare strategie o per disabilitare la strategia specificata e usare invece una strategia predefinita. Per maggiori informazioni, consultare la sezione Strategia di esecuzione della sospensione (EF6 e versioni successive).

Un'altra tecnica per usare strategie di ripetizione specifiche per singole operazioni consiste nel creare un'istanza della classe di strategia necessaria, fornire le impostazioni desiderate attraverso dei parametri e quindi richiamare il metodo ExecuteAsync.

var executionStrategy = new SqlAzureExecutionStrategy(5, TimeSpan.FromSeconds(4));
var blogs = await executionStrategy.ExecuteAsync(
    async () =>
    {
        using (var db = new BloggingContext("Blogs"))
        {
            // Acquire some values asynchronously and return them
        }
    },
    new CancellationToken()
);

Il modo più semplice per usare una classe DbConfiguration consiste nell'individuarla nello stesso assembly della classe DbContext. Questo metodo, tuttavia, non è appropriato quando lo stesso contesto è richiesto in scenari diversi, ad esempio in varie strategie di ripetizione dei tentativi, interattiva o in background. Se i diversi contesti vengono eseguiti in AppDomain distinti, è possibile usare il supporto incorporato per specificare le classi di configurazione nel file di configurazione o impostarle in modo esplicito tramite codice. Se invece i diversi contesti devono essere eseguiti nello stesso AppDomain, sarà necessaria una soluzione personalizzata.

Per maggiori informazioni, consultare la sezione Configurazione basata su codice (EF6 o versioni successive).

La tabella seguente mostra le impostazioni predefinite per i criteri di ripetizione dei tentativi incorporati quando si usa Entity Framework 6.

Impostazione Default value significato
Criteri Esponenziale Backoff esponenziale.
MaxRetryCount 5 Numero massimo di tentativi.
MaxDelay 30 secondi Ritardo massimo tra i tentativi. Questa valore non influisce sulla modalità di calcolo della serie di ritardi. Definisce solo un limite superiore.
DefaultCoefficient 1 secondo Coefficiente per il calcolo del backoff esponenziale. Questo valore non può essere modificato.
DefaultRandomFactor 1.1 Moltiplicatore usato per aggiungere un ritardo casuale per ogni voce. Questo valore non può essere modificato.
DefaultExponentialBase 2 Moltiplicatore usato per calcolare il ritardo successivo. Questo valore non può essere modificato.

Linee guida sull'uso dei criteri di ripetizione dei tentativi

Quando si accede al database SQL con Entity Framework 6, tenere presente le linee guida seguenti:

  • Scegliere il tipo di servizio appropriato (condiviso o premium). Un'istanza condivisa può subire limitazioni o ritardi di connessione maggiori rispetto alla media perché può essere usata da altri tenant del server condiviso. Se sono necessarie prestazioni prevedibili o affidabili operazioni di bassa latenza, valutare la possibilità di scegliere il tipo servizio premium.

  • Per il database SQL di Azure non è consigliabile usare una strategia a intervalli fissi, bensì una strategia di backoff esponenziale, poiché il servizio può essere sovraccarico e intervalli più lunghi concedono più tempo per il ripristino del servizio.

  • Quando si definiscono le connessioni, scegliere un valore appropriato per i timeout di connessione e dei comandi. I timeout devono essere definiti in base alla progettazione della logica di business e tramite una serie di test. Potrebbe essere necessario modificare questi valori nel tempo man mano che i volumi dei dati o dei processi di business cambiano. Un timeout troppo breve può comportare errori di connessione prematuri quando il database è occupato, mentre un timeout troppo lungo può impedire che la logica di ripetizione dei tentativi funzioni correttamente, poiché l'intervallo di attesa prima che venga rilevata una connessione non riuscita è troppo lungo. Sebbene il valore di timeout sia un componente della latenza end-to-end, non è possibile determinare facilmente il numero di comandi che verranno eseguiti durante il salvataggio del contesto. È possibile modificare il timeout predefinito impostando la proprietà CommandTimeout dell'istanza DbContext.

  • Entity Framework supporta le configurazioni di ripetizione dei tentativi definite nei file di configurazione. Per ottenere la massima flessibilità in Azure, tuttavia, è opportuno valutare la possibilità di creare la configurazione a livello di codice all'interno dell'applicazione. I parametri specifici dei criteri di ripetizione dei tentativi, ad esempio il numero di tentativi e l'intervallo tra di essi, possono essere archiviati nel file di configurazione del servizio e usati in fase di esecuzione per creare i criteri appropriati. In questo modo è possibile modificare le impostazioni senza dover riavviare l'applicazione.

È consigliabile iniziare le operazioni di ripetizione dei tentativi usando le impostazioni seguenti. Non è possibile specificare l'intervallo tra i tentativi (si tratta di un valore fisso generato come sequenza esponenziale); è possibile specificare solo i valori massimi, come illustrato di seguito, a meno che non sia stata creata una strategia di ripetizione dei tentativi personalizzata. Queste impostazioni sono di utilizzo generico ed è quindi necessario monitorare le operazioni e personalizzare i valori in base allo scenario.

Contesto Latenza massima destinazione
esempio E2E
Criterio di ripetizione Impostazioni Valori Funzionamento
Interattivo, interfaccia utente
o in primo piano
2 secondi Esponenziale MaxRetryCount
MaxDelay
3
750 ms
Tentativo di 1 - intervallo di 0 sec
Tentativo 2 - intervallo di 750 ms
Tentativo 3 - intervallo di 750 ms
Background
o batch
30 secondi Esponenziale MaxRetryCount
MaxDelay
5
12 secondi
Tentativo di 1 - intervallo di 0 sec
Tentativo 2 - intervallo di ~1 sec
Tentativo 3 - intervallo di ~3 sec
Tentativo 4 - intervallo di ~7 sec
Tentativo 5 - intervallo di 12 sec

Nota

Gli obiettivi di latenza end-to-end presuppongono il timeout predefinito per le connessioni al servizio. Se si specifica un timeout di connessione più lungo, la latenza end-to-end verrà estesa di questo intervallo di tempo aggiuntivo per ogni nuovo tentativo.

Esempi

L'esempio di codice seguente definisce una soluzione di accesso ai dati semplice che usa Entity Framework. Imposta una strategia di ripetizione dei tentativi specifica tramite la definizione di un'istanza di una classe denominata BlogConfiguration che estende DbConfiguration.

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.SqlServer;
using System.Threading.Tasks;

namespace RetryCodeSamples
{
    public class BlogConfiguration : DbConfiguration
    {
        public BlogConfiguration()
        {
            // Set up the execution strategy for SQL Database (exponential) with 5 retries and 12 sec delay.
            // These values could be loaded from configuration rather than being hard-coded.
            this.SetExecutionStrategy(
                    "System.Data.SqlClient", () => new SqlAzureExecutionStrategy(5, TimeSpan.FromSeconds(12)));
        }
    }

    // Specify the configuration type if more than one has been defined.
    // [DbConfigurationType(typeof(BlogConfiguration))]
    public class BloggingContext : DbContext
    {
        // Definition of content goes here.
    }

    class EF6CodeSamples
    {
        public async static Task Samples()
        {
            // Execution strategy configured by DbConfiguration subclass, discovered automatically or
            // or explicitly indicated through configuration or with an attribute. Default is no retries.
            using (var db = new BloggingContext("Blogs"))
            {
                // Add, edit, delete blog items here, then:
                await db.SaveChangesAsync();
            }
        }
    }
}

Altri esempi sull'uso del meccanismo di ripetizione dei tentavi in Entity Framework sono disponibili in Resilienza della connessione/logica di ripetizione dei tentativi.

Database SQL con Entity Framework Core

Entity Framework Core è un mapper relazionale a oggetti che consente agli sviluppatori .NET Core di usare dati mediante oggetti specifici di dominio. Elimina la necessità di gran parte del codice di accesso ai dati che in genere gli sviluppatori devono scrivere. Questa versione di Entity Framework è stata scritta da zero e non eredita automaticamente tutte le funzionalità di EF6.x.

Meccanismo di ripetizione dei tentativi

Quando si accede al database SQL con Entity Framework Core, il supporto per la ripetizione di tentativi viene offerto attraverso un meccanismo denominato Resilienza della connessione. Resilienza connessione è stato introdotto in EF Core 1.1.0.

La principale astrazione è l'interfaccia IExecutionStrategy. La strategia di esecuzione per SQL Server, che include SQL Azure, riconosce i tipi di eccezione per cui è possibile ripetere i tentativi e dispone di impostazioni predefinite ragionevoli per un numero massimo ripetizione dei tentativi, intervalli tra di essi e così via.

Esempi

Il codice seguente abilita le ripetizioni automatiche di tentativi quando si configura l'oggetto DbContext, che rappresenta una sessione con il database.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer(
            @"Server=(localdb)\mssqllocaldb;Database=EFMiscellaneous.ConnectionResiliency;Trusted_Connection=True;",
            options => options.EnableRetryOnFailure());
}

Il codice seguente illustra come eseguire una transazione con la ripetizione di tentativi automatica, usando una strategia di esecuzione. La transazione viene definita in un delegato. Se si verifica un errore temporaneo, la strategia di esecuzione chiamerà nuovamente il delegato.

using (var db = new BloggingContext())
{
    var strategy = db.Database.CreateExecutionStrategy();

    strategy.Execute(() =>
    {
        using (var transaction = db.Database.BeginTransaction())
        {
            db.Blogs.Add(new Blog { Url = "https://blogs.msdn.com/dotnet" });
            db.SaveChanges();

            db.Blogs.Add(new Blog { Url = "https://blogs.msdn.com/visualstudio" });
            db.SaveChanges();

            transaction.Commit();
        }
    });
}

Archiviazione di Azure

I servizi di archiviazione di Azure includono funzioni di archiviazione di BLOB, file e code di archiviazione.

BLOB, code e file

La classe ClientOptions è il tipo di base per tutti i tipi di opzioni client ed espone diverse opzioni client comuni, ad esempio Diagnostica, Nuovo tentativo, Trasporto. Per fornire le opzioni di configurazione client per la connessione ad Archiviazione code, BLOB e file di Azure, è necessario usare il tipo derivato corrispondente. Nell'esempio successivo si usa la classe QueueClientOptions (derivata da ClientOptions) per configurare la connessione di un client al servizio di accodamento di Azure. La proprietà Retry è il set di opzioni che possono essere specificate per determinare come eseguire i tentativi e come stabilire che un errore è idoneo per la ripetizione.

using System;
using System.Threading;
using Azure.Core;
using Azure.Identity;
using Azure.Storage;
using Azure.Storage.Queues;
using Azure.Storage.Queues.Models;

namespace RetryCodeSamples
{
    class AzureStorageCodeSamples {

        public async static Task Samples() {

               // Provide the client configuration options for connecting to Azure Queue Storage
                QueueClientOptions queueClientOptions = new QueueClientOptions()
                {
                    Retry = {
                    Delay = TimeSpan.FromSeconds(2),     //The delay between retry attempts for a fixed approach or the delay on which to base
                                                         //calculations for a backoff-based approach
                    MaxRetries = 5,                      //The maximum number of retry attempts before giving up
                    Mode = RetryMode.Exponential,        //The approach to use for calculating retry delays
                    MaxDelay = TimeSpan.FromSeconds(10)  //The maximum permissible delay between retry attempts
                    },

                    GeoRedundantSecondaryUri = new Uri("https://...")
                    // If the GeoRedundantSecondaryUri property is set, the secondary Uri will be used for GET or HEAD requests during retries.
                    // If the status of the response from the secondary Uri is a 404, then subsequent retries for the request will not use the
                    // secondary Uri again, as this indicates that the resource may not have propagated there yet.
                    // Otherwise, subsequent retries will alternate back and forth between primary and secondary Uri.
                };

                Uri queueServiceUri = new Uri("https://storageaccount.queue.core.windows.net/");
                string accountName = "Storage account name";
                string accountKey = "storage account key";

                // Create a client object for the Queue service, including QueueClientOptions.
                QueueServiceClient serviceClient = new QueueServiceClient(queueServiceUri, new DefaultAzureCredential(), queueClientOptions);

                CancellationTokenSource source = new CancellationTokenSource();
                CancellationToken cancellationToken = source.Token;

                // Return an async collection of queues in the storage account.
                var queues = serviceClient.GetQueuesAsync(QueueTraits.None, null, cancellationToken);

Supporto delle tabelle

Nota

Il pacchetto Nuget WindowsAzure.Storage e il pacchetto NuGet Microsoft.Azure.Cosmos.Table sono stati deprecati. Per il supporto delle tabelle di Azure, consultare la sezione Pacchetto NuGet Azure.Data.Tables

Meccanismo di ripetizione dei tentativi

La libreria client si basa sulla Libreria Core di Azure, ovvero una libreria che fornisce servizi di taglio incrociato ad altre librerie client.

Esistono molti motivi per cui può verificarsi un errore quando un'applicazione client tenta di inviare una richiesta di rete a un servizio. Alcuni esempi sono timeout, errori dell'infrastruttura di rete, servizio che rifiuta la richiesta a causa della limitazione o della disponibilità, terminazione dell'istanza del servizio a causa del ridimensionamento del servizio, istanza del servizio che verrà sostituita con un'altra versione, arresto anomalo del servizio a causa di un'eccezione non gestita e così via. Offrendo un meccanismo di ripetizione dei tentativi predefinito (con una configurazione predefinita che il consumer può eseguire l'override), gli SDK e l'applicazione del consumer diventano resilienti a questi tipi di errori. Si noti che alcuni servizi addebitano denaro reale per ogni richiesta e quindi i consumatori dovrebbero essere in grado di disabilitare completamente i tentativi se preferiscono risparmiare denaro rispetto alla resilienza.

Configurazione dei criteri

I criteri di ripetizione dei tentativi sono configurati a livello di codice. La configurazione si basa sulla classe RetryOption. Esiste un attributo in TableClientOptions ereditato da ClientOptions

var tableClientOptions = new TableClientOptions();
tableClientOptions.Retry.Mode = RetryMode.Exponential;
tableClientOptions.Retry.MaxRetries = 5;
var serviceClient = new TableServiceClient("<endpoint>", new DefaultAzureCredential(), tableClientOptions);

Le tabelle seguenti mostrano le possibilità per i criteri di ripetizione dei tentativi predefiniti.

RetryOption

Impostazione significato
Ritardo Ritardo tra i tentativi di ripetizione per un approccio fisso o il ritardo su cui basare i calcoli per un approccio basato sul backoff. Se il servizio fornisce un'intestazione di risposta Retry-After, il successivo tentativo verrà ritardato dalla durata specificata dal valore dell'intestazione.
MaxDelay Ritardo massimo consentito tra i tentativi quando il servizio non fornisce un'intestazione di risposta Retry-After. Se il servizio fornisce un'intestazione di risposta Retry-After, il successivo tentativo verrà ritardato dalla durata specificata dal valore dell'intestazione.
Modalità Approccio da usare per calcolare i ritardi di ripetizione dei tentativi.
NetworkTimeout Timeout applicato a una singola operazione di rete.

RetryMode

Impostazione significato
Esponenziale I tentativi di ripetizione ritarderanno in base a una strategia di backoff, in cui ogni tentativo aumenterà la durata di attesa prima di riprovare.
MaxDelay I tentativi di ripetizione vengono eseguiti a intervalli fissi; ogni ritardo è una durata coerente.

Telemetria

Il modo più semplice per visualizzare i log consiste nell'abilitare la registrazione della console. Per creare un listener di log di Azure SDK che restituisce messaggi nella console, usare il metodo AzureEventSourceListener.CreateConsoleLogger.

// Setup a listener to monitor logged events.
using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger();

Esempi

L'esecuzione dell'esempio di codice seguente con l'emulatore di archiviazione arrestata consentirà di visualizzare informazioni sui tentativi nella console.

using Azure.Core;
using Azure.Core.Diagnostics;
using Azure.Data.Tables;
using Azure.Data.Tables.Models;
using Azure.Identity;

namespace RetryCodeSamples
{
    class AzureStorageCodeSamples
    {
        private const string tableName = "RetryTestTable";

        public async static Task SamplesAsync()
        {
            // Setup a listener to monitor logged events.
            using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger();

            var tableClientOptions = new TableClientOptions();
            tableClientOptions.Retry.Mode = RetryMode.Exponential;
            tableClientOptions.Retry.MaxRetries = 5;

            var serviceClient = new TableServiceClient("<endpoint>", new DefaultAzureCredential(), tableClientOptions);

            TableItem table = await serviceClient.CreateTableIfNotExistsAsync(tableName);
            Console.WriteLine($"The created table's name is {table.Name}.");
        }
    }
}

Linee guida generali su REST e sulla ripetizione di tentativi

Quando si accede a servizi di Azure o di terze parti, tenere presente quanto segue:

  • Usare un approccio sistematico per gestire la ripetizione di tentativi, ad esempio sotto forma di codice riusabile, in modo da poter applicare una metodologia coerente tra tutti i client e le soluzioni.

  • Valutare la possibilità di usare un framework di ripetizione dei tentativi come Polly per gestire la ripetizione di tentativi se nel client o nel servizio di destinazione non è incorporato un meccanismo di ripetizione dei tentativi. In questo modo, sarà possibile implementare un comportamento coerente per la gestione dei nuovi tentativi e usufruire di un'adeguata strategia di ripetizione dei tentativi predefinita per il servizio di destinazione. Potrebbe essere necessario, tuttavia, creare un codice di ripetizione dei tentativi personalizzato per i servizi che presentano un comportamento non standard, ovvero non basato sulle eccezioni per stabilire gli errori temporanei, oppure se si desidera usare un metodo Retry-Response per gestire il comportamento di ripetizione dei tentativi.

  • La logica di rilevamento degli errori temporanei dipenderà dall'API client effettiva usata per richiamare le chiamate REST. Alcuni client, ad esempio la nuova classe HttpClient , non genereranno eccezioni per le richieste completate con un codice di stato HTTP di errore.

  • Il codice di stato HTTP restituito dal servizio consente di stabilire se l'errore è temporaneo. È possibile che sia necessario esaminare le eccezioni generate da un client o dal framework di ripetizione dei tentativi per accedere al codice di stato o determinare il tipo di eccezione equivalente. I seguenti codici HTTP indicano, in genere, che è opportuno eseguire un nuovo tentativo:

    • 408 - Timeout richiesta
    • 429 Troppe richieste
    • 500 Errore interno del server
    • 502 Gateway non valido
    • 503 Servizio non disponibile
    • 504 - Timeout gateway
  • Se si usa una logica di ripetizione dei tentativi basata sulle eccezioni, i valori seguenti indicano un errore temporaneo in cui non è possibile stabilire una connessione:

    • WebExceptionStatus.ConnectionClosed
    • WebExceptionStatus.ConnectFailure
    • WebExceptionStatus.Timeout
    • WebExceptionStatus.RequestCanceled
  • In caso di stato non disponibile di un servizio, l'intervallo di tempo appropriato prima di un nuovo tentativo può essere riportato nell'intestazione della risposta Retry-After o in un'altra intestazione personalizzata del servizio. Alcuni servizi possono anche inviare informazioni aggiuntive come intestazioni personalizzate o incorporate nel contenuto della risposta.

  • Non eseguire nuovi tentativi in caso di codici di stato che rappresentano errori client (errori nell'intervallo 4xx), a eccezione di 408 - Timeout richiesta e 429 - Numero eccessivo di richieste.

  • Verificare accuratamente le strategie e i meccanismi di ripetizione dei tentativi in condizioni diverse, ad esempio in vari stati di rete e carichi di sistema.

Strategie di ripetizione dei tentativi

Di seguito sono riportati i tipi intervallo più comuni nelle strategie di ripetizione dei tentativi:

  • Esponenziale. Criteri di ripetizione dei tentativi che eseguono un numero prestabilito di nuovi tentativi e usano un approccio di backoff esponenziale casuale per determinare l'intervallo di tempo tra i tentativi. Ad esempio:

    var random = new Random();
    
    var delta = (int)((Math.Pow(2.0, currentRetryCount) - 1.0) *
                random.Next((int)(this.deltaBackoff.TotalMilliseconds * 0.8),
                (int)(this.deltaBackoff.TotalMilliseconds * 1.2)));
    var interval = (int)Math.Min(checked(this.minBackoff.TotalMilliseconds + delta),
                    this.maxBackoff.TotalMilliseconds);
    retryInterval = TimeSpan.FromMilliseconds(interval);
    
  • Incrementale. Strategia di ripetizione dei tentativi con un numero prestabilito di nuovi tentativi e un intervallo di tempo incrementale tra i tentativi. Ad esempio:

    retryInterval = TimeSpan.FromMilliseconds(this.initialInterval.TotalMilliseconds +
                    (this.increment.TotalMilliseconds * currentRetryCount));
    
  • LinearRetry. Criteri di ripetizione dei tentativi che eseguono un numero prestabilito di nuovi tentativi e usano un intervallo di tempo fisso tra i tentativi. Ad esempio:

    retryInterval = this.deltaBackoff;
    

Gestione degli errori temporanei con Polly

Polly è una libreria per gestire a livello di codice la ripetizione dei tentativi e le strategie dell'interruttore. Il progetto Polly è membro di .NET Foundation. Per i servizi in cui il client non supporta in modo nativo la ripetizione dei tentativi, Polly è una valida alternativa ed evita la necessità di scrivere il codice personalizzato per la ripetizione dei tentativi, la cui corretta implementazione può risultare difficile. Polly offre anche un modo per tracciare gli errori quando questi si verificano, in modo che sia possibile registrare i tentativi.

Passaggi successivi