Delen via


Richtlijnen voor opnieuw proberen voor Azure-services

De meeste Azure-services en client-SDK's bevatten een mechanisme voor opnieuw proberen. Deze verschillen echter omdat elke service verschillende kenmerken en vereisten heeft, waardoor elk mechanisme voor opnieuw proberen is afgestemd op een specifieke service. Deze handleiding bevat een overzicht van de mechanismefuncties voor opnieuw proberen voor de meeste Azure-services en bevat informatie waarmee u het mechanisme voor opnieuw proberen voor die service kunt gebruiken, aanpassen of uitbreiden.

Raadpleeg Richtlijnen voor opnieuw proberenvoor algemene richtlijnen voor de afhandeling van tijdelijke fouten en het opnieuw proberen van verbindingen en bewerkingen voor services en bronnen.

De volgende tabel geeft een overzicht van de functies voor opnieuw proberen voor de Azure-services die in deze handleiding worden beschreven.

Onderhoud Mogelijkheden voor opnieuw proberen Beleidsconfiguratie Scope Telemetriefuncties
Microsoft Entra ID Systeemeigen in MSAL-bibliotheek Ingesloten in MSAL-bibliotheek Intern Geen
Azure Cosmos DB Systeemeigen in service Niet-configureerbaar Globaal TraceSource
Data Lake Store Systeemeigen in client Niet-configureerbaar Afzonderlijke bewerkingen Geen
Event Hubs Systeemeigen in client Via programmacode Klant Geen
IoT Hub Systeemeigen in client-SDK Via programmacode Klant Geen
Azure Cache voor Redis Systeemeigen in client Via programmacode Klant TextWriter
Zoeken Systeemeigen in client Via programmacode Klant Gebeurtenistracering voor Windows (ETW) of aangepast
Service Bus Systeemeigen in client Via programmacode Naamruimtebeheer, berichtenfactory en client ETW
Service Fabric Systeemeigen in client Via programmacode Klant Geen
SQL Database met ADO.NET Polly Declaratief en via programmacode Losse instructies of codeblokken Aanpassen
SQL Database met Entity Framework Systeemeigen in client Via programmacode Algemeen per toepassingsdomein Geen
SQL-Database met Entity Framework Core Systeemeigen in client Via programmacode Algemeen per toepassingsdomein Geen
Storage Systeemeigen in client Via programmacode Client en individuele bewerkingen TraceSource

Notitie

Voor de meeste ingebouwde mechanismen voor opnieuw proberen van Azure is er momenteel geen manier om een ander beleid voor opnieuw proberen toe te passen voor verschillende typen fouten of uitzonderingen. U moet een beleid configureren dat de optimale gemiddelde prestaties en beschikbaarheid biedt. Eén manier om het beleid te verfijnen is het analyseren van logboekbestanden om te bepalen welk type tijdelijke fouten optreedt.

Microsoft Entra ID

Microsoft Entra ID is een uitgebreide cloudoplossing voor identiteits- en toegangsbeheer die kerndirectoryservices, geavanceerde identiteitsbeheer, beveiliging en toegangsbeheer voor toepassingen combineert. Microsoft Entra ID biedt ontwikkelaars ook een identiteitsbeheerplatform voor het leveren van toegangsbeheer aan hun toepassingen, op basis van gecentraliseerd beleid en regels.

Notitie

Zie How to use an Azure VM Managed Service Identity (MSI) for token acquisition (Managed Service Identity) voor richtlijnen voor opnieuw proberen voor Managed Service Identity-eindpunten.

Mechanisme voor opnieuw proberen

Er is een ingebouwd mechanisme voor opnieuw proberen voor Microsoft Entra ID in de Microsoft Authentication Library (MSAL). Om onverwachte vergrendelingen te voorkomen, raden we aan dat bibliotheken van derden en toepassingscode mislukte verbindingen niet opnieuw proberen, maar MSAL toestaan om nieuwe pogingen af te handelen.

Gebruiksrichtlijnen voor opnieuw proberen

Houd rekening met de volgende richtlijnen bij het gebruik van Microsoft Entra ID:

  • Gebruik indien mogelijk de MSAL-bibliotheek en de ingebouwde ondersteuning voor nieuwe pogingen.
  • Als u de REST API voor Microsoft Entra ID gebruikt, voert u de bewerking opnieuw uit als de resultaatcode 429 (Te veel aanvragen) of een fout in het bereik 5xx is. Probeer het niet opnieuw voor andere fouten.
  • Voor 429-fouten moet u het alleen opnieuw proberen na de tijd die wordt aangegeven in de header Opnieuw proberen na .
  • Voor 5xx-fouten gebruikt u exponentieel uitstel, waarbij u ten minste 5 seconden na het antwoord opnieuw probeert.
  • Probeer het niet opnieuw op fouten dan 429 en 5xx.

Volgende stappen

Azure Cosmos DB

Azure Cosmos DB is een volledig beheerde database met meerdere modellen die ondersteuning biedt voor schemaloze JSON-gegevens. De service levert configureerbare en betrouwbare prestaties en een ingebouwde JavaScript-transactieverwerking. Daarbij is de service speciaal ontwikkeld voor in de cloud en is deze flexibel schaalbaar.

Mechanisme voor opnieuw proberen

De Azure Cosmos DB SDK's proberen automatisch opnieuw op bepaalde foutvoorwaarden en gebruikerstoepassingen worden aangemoedigd om hun eigen beleid voor opnieuw proberen te hebben. Zie de handleiding voor het ontwerpen van flexibele toepassingen met Azure Cosmos DB SDK's voor een volledige lijst met foutvoorwaarden en wanneer u het opnieuw moet proberen.

Telemetrie

Afhankelijk van de taal van uw toepassing worden diagnostische gegevens en telemetrie weergegeven als logboeken of gepromoveerde eigenschappen van de bewerkingsreacties. Zie de sectie Diagnostische gegevens vastleggen in de Azure Cosmos DB C#SDK en Azure Cosmos DB Java SDK voor meer informatie.

Data Lake Store

Data Lake Storage Gen2 maakt Azure Storage de basis voor het bouwen van zakelijke data lakes in Azure. Met Data Lake Storage Gen2 kunt u eenvoudig enorme hoeveelheden gegevens beheren.

De Azure Storage Files Data Lake-clientbibliotheek bevat alle mogelijkheden die nodig zijn om ontwikkelaars, gegevenswetenschappers en analisten gemakkelijk te maken om gegevens van elke grootte, vorm en snelheid op te slaan en alle soorten verwerking en analyse uit te voeren op platforms en talen.

Mechanisme voor opnieuw proberen

Met DataLakeServiceClient kunt u Azure Data Lake-servicebronnen en -bestandssystemen bewerken. Het opslagaccount biedt de naamruimte op het hoogste niveau voor de Data Lake-service. Wanneer u de client maakt, kunt u de clientconfiguratieopties opgeven om verbinding te maken met de Azure Data Lake-service (DataLakeClientOptions). De DataLakeClientOptions bevat een eigenschap Opnieuw proberen (overgenomen van Azure.Core.ClientOptions) die kan worden geconfigureerd (RetryOptions-klasse).

Telemetrie

Het bewaken van het gebruik en de prestaties van Azure Storage is een belangrijk onderdeel van het operationeel maken van uw service. Voorbeelden hiervan zijn frequente bewerkingen, bewerkingen met hoge latentie of bewerkingen die leiden tot beperking aan de servicezijde.

Alle telemetriegegevens voor uw opslagaccount zijn beschikbaar via Azure Storage-logboeken in Azure Monitor. Deze functie integreert uw opslagaccount met Log Analytics en Event Hubs, terwijl u ook logboeken kunt archiveren naar een ander opslagaccount. Als u de volledige lijst met metrische gegevens en resourcelogboeken en het bijbehorende schema wilt bekijken, raadpleegt u de azure Storage-referentie voor bewakingsgegevens.

Event Hubs

Azure Event Hubs is een hyperscale telemetrieopnameservice waarmee miljoenen gebeurtenissen worden verzameld, getransformeerd en opgeslagen.

Mechanisme voor opnieuw proberen

Gedrag voor opnieuw proberen in de clientbibliotheek van Azure Event Hubs wordt geregeld via de eigenschap RetryPolicy van de klasse EventHubClient. Het standaardbeleid wordt opnieuw geprobeerd met exponentieel uitstel wanneer Azure Event Hubs een tijdelijke EventHubsException of een OperationCanceledException. Het standaardbeleid voor opnieuw proberen voor Event Hubs is om het maximaal 9 keer opnieuw te proberen met een exponentiële uitsteltijd van maximaal 30 seconden.

Opmerking

EventHubClient client = EventHubClient.CreateFromConnectionString("[event_hub_connection_string]");
client.RetryPolicy = RetryPolicy.Default;

Volgende stappen

Azure Event Hubs-clientbibliotheek voor .NET

IoT Hub

Azure IoT Hub is een service voor het verbinden, bewaken en beheren van apparaten om IoT-toepassingen (Internet of Things) te ontwikkelen.

Mechanisme voor opnieuw proberen

De Azure IoT-apparaat-SDK kan fouten detecteren in het netwerk, protocol of de toepassing. Op basis van het fouttype controleert de SDK of een nieuwe poging moet worden uitgevoerd. Als de fout kan worden hersteld, begint de SDK opnieuw te proberen met behulp van het geconfigureerde beleid voor opnieuw proberen.

Het standaardbeleid voor opnieuw proberen is exponentieel uitstel met willekeurige jitter, maar kan worden geconfigureerd.

Beleidsconfiguratie

Beleidsconfiguratie verschilt per taal. Zie voor meer informatie de configuratie van beleid voor opnieuw proberen van IoT Hub.

Volgende stappen

Azure Cache voor Redis

Azure Cache voor Redis is een snelle gegevenstoegang en cacheservice met lage latentie op basis van de populaire opensource Redis-cache. Het is veilig, beheerd door Microsoft en is toegankelijk vanuit elke toepassing in Azure.

De richtlijnen in dit gedeelte zijn gebaseerd op het gebruik van de client StackExchange.Redis voor toegang tot de cache. Een lijst met andere geschikte clients vindt u op de Redis-website en deze kunnen verschillende mechanismen voor opnieuw proberen gebruiken.

De StackExchange.Redis-client maakt gebruik van multiplexing via één verbinding. De aanbevolen methode is bij het opstarten van de toepassing een exemplaar van de client te maken en dit exemplaar te gebruiken voor alle bewerkingen met de cache. Er wordt dus slechts eenmaal verbinding gemaakt met de cache en daarom hebben alle richtlijnen in dit gedeelte betrekking op het beleid voor opnieuw proberen voor deze initiële verbinding en niet voor elke bewerking die toegang heeft tot de cache.

Mechanisme voor opnieuw proberen

De StackExchange.Redis-client maakt gebruik van een verbindingsbeheerklasse die is geconfigureerd via een set opties, waaronder:

  • ConnectRetry. Het aantal malen dat een mislukte verbinding met de cache opnieuw wordt geprobeerd.
  • ReconnectRetryPolicy. De strategie voor opnieuw proberen die moet worden gebruikt.
  • ConnectTimeout. De maximale wachttijd in milliseconden.

Beleidsconfiguratie

Beleid voor opnieuw proberen wordt via de programmacode geconfigureerd, waarbij de opties voor de client worden ingesteld voordat u verbinding maakt met de cache. Dit kan worden gedaan door een exemplaar van de klasse ConfigurationOptions te maken, de eigenschappen ervan te vullen en deze door te geven aan de methode Connect.

De ingebouwde klassen ondersteunen lineaire (constante) vertraging en exponentieel uitstel met willekeurige intervallen tussen nieuwe pogingen. U kunt ook een aangepast beleid voor opnieuw proberen maken door de interface IReconnectRetryPolicy te implementeren.

In het volgende voorbeeld wordt een strategie voor opnieuw proberen met exponentieel uitstel geconfigureerd.

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

U kunt de opties ook opgeven als een tekenreeks en deze doorgeven aan de methode Connect. De eigenschap ReconnectRetryPolicy kan niet op deze manier worden ingesteld, alleen via code.

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

U kunt opties ook rechtstreeks opgeven wanneer u verbinding maakt met de cache.

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

Zie Stack Exchange Redis-configuratie in de documentatie over StackExchange.Redis voor meer informatie.

In de volgende tabellen ziet u de standaardinstellingen voor het ingebouwde beleid voor opnieuw proberen.

Context Instelling Standaardwaarde
(v 1.2.2)
Betekenis
ConfigurationOptions ConnectRetry

ConnectTimeout

SyncTimeout

ReconnectRetryPolicy
3

Maximaal 5000 ms plus SyncTimeout
1000

LinearRetry 5000 ms
Het aantal keren dat verbindingspogingen moeten worden herhaald tijdens de eerste verbindingsbewerking.
Time-out (ms) voor verbindingsbewerkingen. Geen vertraging tussen nieuwe pogingen.
Tijd (ms) die is toegestaan voor synchrone bewerkingen.

Elke 5000 ms. opnieuw proberen.

Notitie

Voor synchrone bewerkingen kan SyncTimeout de end-to-end-latentie vergroten, maar als u de waarde te laag instelt, kan dit leiden tot te lange time-outs. Zie Problemen met Azure Cache voor Redis oplossen. In het algemeen dient u synchrone bewerkingen te vermijden en in plaats daarvan asynchrone bewerkingen te gebruiken. Zie Pijplijnen en Multiplexers voor meer informatie.

Gebruiksrichtlijnen voor opnieuw proberen

Houd rekening met de volgende richtlijnen bij het gebruik van Azure Cache voor Redis:

  • De StackExchange Redis-client beheert zijn een eigen nieuwe pogingen, maar alleen wanneer een verbinding met de cache tot stand wordt gebracht wanneer de toepassing voor het eerst wordt gestart. U kunt de time-out voor de verbinding, het aantal nieuwe pogingen en de tijd tussen nieuwe pogingen om deze verbinding tot stand te brengen configureren, maar het beleid voor opnieuw proberen is niet van toepassing op bewerkingen in de cache.
  • In plaats van een groot aantal nieuwe pogingen te gebruiken, kunt u overwegen terug te vallen op toegang tot de oorspronkelijke gegevensbron.

Telemetrie

U kunt informatie verzamelen over verbindingen (maar geen andere bewerkingen) met behulp van een TextWriter.

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

Hieronder ziet u een voorbeeld van de uitvoer die hierbij wordt gegenereerd.

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...
...

Voorbeelden

In het volgende voorbeeld wordt een constante (lineair) vertraging tussen nieuwe pogingen geconfigureerd wanneer de StackExchange.Redis-client wordt geïnitialiseerd. In dit voorbeeld zie u hoe voor het instellen van de configuratie een exemplaar van ConfigurationOptions wordt gebruikt.

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;
                }
            }
        }
    }
}

In het volgende voorbeeld wordt de configuratie ingesteld door de opties als een tekenreeks op te geven. De time-out voor de verbinding is de maximale tijd die moet worden gewacht op een verbinding met de cache, niet de vertraging tussen nieuwe pogingen. De eigenschap ReconnectRetryPolicy kan alleen worden ingesteld door code.

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;
                }
            }
        }
    }
}

Zie Configuratie op de projectwebsite voor meer voorbeelden.

Volgende stappen

Azure Search kan worden gebruikt om krachtige en geavanceerde zoekfuncties toe te voegen aan een website of toepassing, de zoekresultaten snel en gemakkelijk aan te passen en uitgebreide en afgestemde rangschikkingsmodellen te creëren.

Mechanisme voor opnieuw proberen

Azure SDK voor .NET bevat een Azure.Search.Documents-clientbibliotheek van het Azure SDK-team dat functioneel gelijk is aan de vorige clientbibliotheek, Microsoft.Azure.Search.

Gedrag voor opnieuw proberen in Microsoft.Azure.Search wordt beheerd door de methode SetRetryPolicy in de klassen SearchServiceClient en SearchIndexClient. Het standaardbeleid voert nieuwe pogingen uit met exponentieel uitstel wanneer Azure Search de reactie 5xx of 408 (time-out van aanvraag) retourneert.

Gedrag voor opnieuw proberen in Azure.Search.Documents wordt beheerd door SearchClientOptions (het maakt deel uit van de SearchClient-constructor) in de eigenschap Opnieuw proberen, die deel uitmaakt van de klasse Azure.Core.RetryOptions(waar alle configuraties beschikbaar zijn).

Telemetrie

U kunt traceren met ETW of door een aangepaste traceringsprovider te registreren. Raadpleeg de AutoRest-documentatie voor meer informatie.

Service Bus

Service Bus is een berichtenplatform in de cloud dat losjes gekoppelde berichtuitwisseling met verbeterde schaal en tolerantie biedt voor onderdelen van een toepassing, ongeacht of die in de cloud of on-premises worden gehost.

Mechanisme voor opnieuw proberen

De naamruimte en enkele configuratiedetails zijn afhankelijk van welk Sdk-pakket van de Service Bus-client wordt gebruikt:

Pakket Beschrijving Naamruimte
Azure.Messaging.ServiceBus Azure Service Bus-clientbibliotheek voor .NET Azure.Messaging.ServiceBus
WindowsAzure.ServiceBus Dit pakket is de oudere Service Bus-clientbibliotheek. Hiervoor is .NET Framework 4.5.2 vereist. Microsoft.Azure.ServiceBus

Gebruiksrichtlijnen voor opnieuw proberen

De ServiceBusRetryOptions eigenschap geeft de opties voor opnieuw proberen voor het ServiceBusClient object op:

Instelling Default value Betekenis
CustomRetryPolicy Een aangepast beleid voor opnieuw proberen dat moet worden gebruikt in plaats van de afzonderlijke optiewaarden.
Vertraging 0,8 seconden De vertraging tussen nieuwe pogingen voor een vaste benadering of de vertraging waarop berekeningen voor een back-off-gebaseerde benadering moeten worden gebaseerd.
MaxDelay 60 seconden De maximaal toegestane vertraging tussen nieuwe pogingen.
MaxRetries 3 Het maximum aantal nieuwe pogingen voordat de gekoppelde bewerking is mislukt.
Modus Exponentieel De methode die moet worden gebruikt voor het berekenen van vertragingen voor opnieuw proberen.
TryTimeout 60 seconden De maximale duur die moet worden gewacht op voltooiing van één poging, ongeacht of de eerste poging of een nieuwe poging.

Stel de Mode eigenschap in om de ServiceBusRetryMode te configureren met een van deze waarden:

Eigenschappen Weergegeven als Beschrijving
Exponentieel 1 Nieuwe pogingen worden vertraagd op basis van een back-offstrategie, waarbij elke poging de duur verhoogt die wordt gewacht voordat het opnieuw wordt geprobeerd.
Vast 0 Nieuwe pogingen gebeuren met vaste intervallen; elke vertraging is een consistente duur.

Voorbeeld:

using Azure.Messaging.ServiceBus;

string connectionString = "<connection_string>";
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(connectionString, options);

Telemetrie

Service Bus verzamelt dezelfde soorten bewakingsgegevens als andere Azure-resources. U kunt Azure Service Bus bewaken met behulp van Azure Monitor.

U hebt ook verschillende opties voor het verzenden van telemetrie met de Service Bus .NET-clientbibliotheken.

Opmerking

In het volgende codevoorbeeld ziet u hoe u het Azure.Messaging.ServiceBus pakket gebruikt om:

  • Stel het beleid voor opnieuw proberen in voor een ServiceBusClient gebruik van een nieuwe ServiceBusClientOptions.
  • Maak een nieuw bericht met een nieuw exemplaar van een ServiceBusMessage.
  • Verzend een bericht naar de Service Bus met behulp van de ServiceBusSender.SendMessageAsync(message) methode.
  • Ontvangen met behulp van de ServiceBusReceiver, die worden weergegeven als ServiceBusReceivedMessage objecten.
// using Azure.Messaging.ServiceBus;

using Azure.Messaging.ServiceBus;

string connectionString = "<connection_string>";
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(connectionString, 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);

Volgende stappen

Service Fabric

Het distribueren van betrouwbare services in een Service Fabric-cluster biedt bescherming tegen de meeste potentiële tijdelijke fouten die in dit artikel worden besproken. Sommige tijdelijke fouten zijn echter nog steeds mogelijk. De naamgevingsservice kan bijvoorbeeld midden in een routeringswijziging zitten wanneer een aanvraag binnenkomt, waardoor een uitzondering wordt gegenereerd. Als dezelfde aanvraag 100 milliseconden later komt, slaagt deze waarschijnlijk wel.

Service Fabric beheert dit soort tijdelijke fouten intern. U kunt een aantal instellingen configureren met behulp van de klasse OperationRetrySettings wanneer u uw services instelt. De volgende code laat een voorbeeld zien. In de meeste gevallen is dit niet nodig en zijn de standaardinstellingen prima.

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

Volgende stappen

SQL Database met behulp van ADO.NET

SQL Database is een gehoste SQL-database die beschikbaar is in allerlei afmetingen en zowel als standaardservice (gedeeld) en als premiumservice (niet gedeeld).

Mechanisme voor opnieuw proberen

SQL Database biedt geen ingebouwde ondersteuning voor nieuwe pogingen wanneer toegang wordt verkregen met behulp van ADO.NET. De retourcodes van aanvragen kunnen echter worden gebruikt om te bepalen waarom een aanvraag mislukt. Zie Resourcelimieten voor Azure SQL Database voor meer informatie over het beperken van SQL Database. Zie SQL-foutcodes voor SQL Database-clienttoepassingen voor een overzicht van relevante foutcodes.

U kunt de bibliotheek Polly gebruiken om nieuwe pogingen voor SQL Database te implementeren. Zie Tijdelijke fouten afhandelen met Polly.

Gebruiksrichtlijnen voor opnieuw proberen

Houd rekening met de volgende richtlijnen wanneer u toegang hebt tot SQL Database met behulp van ADO.NET:

  • Kies de juiste service-optie (gedeeld of premium). Een gedeeld exemplaar kan te maken krijgen met langere verbindingsvertragingen en meer beperkingen dan gebruikelijk is doordat andere tenants de gedeelde server gebruiken. Als meer voorspelbare prestaties en betrouwbaardere bewerkingen met een lage latentie zijn vereist, kunt u overwegen de premiumoptie te kiezen.
  • Zorg ervoor dat u nieuwe pogingen uitvoert op het juiste niveau of met de juiste scope om te voorkomen dat niet-idempotente bewerkingen inconsistentie in de gegevens veroorzaken. In het ideale geval moeten alle bewerkingen idempotent zijn, zodat ze kunnen worden herhaald zonder inconsistentie te veroorzaken. Als dit niet het geval is, moet de nieuwe poging worden uitgevoerd op een niveau of bereik waarmee alle gerelateerde wijzigingen ongedaan kunnen worden gemaakt als één bewerking mislukt; Bijvoorbeeld vanuit een transactioneel bereik. Zie Basisbeginselen gegevenstoegangslaag cloudservice: afhandeling van tijdelijke fouten voor meer informatie.
  • Een strategie met een vast interval wordt niet aanbevolen voor gebruik met Azure SQL Database, met uitzondering van interactieve scenario's waarbij er slechts enkele nieuwe pogingen zijn met korte intervallen. Overweeg in plaats daarvan een exponentiële back-off-strategie te gebruiken voor de meeste scenario's.
  • Kies een geschikte waarde voor de time-outs voor verbinding en opdrachten bij het definiëren van verbindingen. Een te korte time-out kan leiden tot voortijdige verbroken verbindingen wanneer de database bezet is. Een te lange time-out kan verhinderen dat de logica voor nieuwe pogingen correct werkt doordat te lang wordt gewacht voordat een mislukte verbinding wordt gedetecteerd. De waarde van de time-out is een onderdeel van de end-to-end-latentie; deze wordt effectief toegevoegd aan de vertraging voor opnieuw proberen die is opgegeven in het beleid voor opnieuw proberen voor elke nieuwe poging.
  • Sluit de verbinding na enkele nieuwe pogingen, zelfs wanneer u een exponentiële logica voor opnieuw proberen gebruikt en voer de bewerking opnieuw uit op een nieuwe verbinding. Als u dezelfde bewerking meerdere malen probeert met dezelfde verbinding, kan dit bijdragen aan verbindingsproblemen. Zie Basisbeginselen gegevenstoegangslaag cloudservice: afhandeling van tijdelijke fouten voor een voorbeeld van deze techniek.
  • Wanneer groepsgewijze verbindingen in gebruik zijn (de standaardinstelling), is er een kans dat dezelfde verbinding wordt gekozen uit de pool, zelfs nadat een verbinding is gesloten en opnieuw is geopend. Zo ja, dan roept u de ClearPool-methode van de Sql Verbinding maken ion-klasse aan om de verbinding te markeren als niet herbruikbaar. U mag dit echter alleen doen nadat meerdere verbindingspogingen zijn mislukt en alleen als u de specifieke klasse van tijdelijke fouten tegenkomt, zoals SQL-time-outs (foutcode -2) met betrekking tot mislukte verbindingen.
  • Als de code voor gegevenstoegang gebruikmaakt van transacties die zijn geïnitieerd als exemplaren van TransactionScope, moet de logica voor opnieuw proberen de verbinding opnieuw openen en een nieuwe transactiescope starten. Daarom moet het codeblok dat opnieuw kan worden geprobeerd, de volledige scope van de transactie omvatten.

Overweeg te beginnen met de volgende instellingen voor het opnieuw proberen van bewerkingen. Deze instellingen zijn algemeen gebruik en u moet de bewerkingen controleren en de waarden aanpassen aan uw eigen scenario.

Context Voorbeelddoel E2E
maximale latentie
Strategie voor opnieuw proberen Instellingen Waarden Hoe werkt het?
Interactief, UI
of voorgrond
2 sec. FixedInterval Aantal nieuwe pogingen
Interval tussen nieuwe pogingen
Eerste snelle poging
3
500 ms
true
Poging 1, vertraging 0 sec.
Poging 2, vertraging 500 ms
Poging 3, vertraging 500 ms
Achtergrond
of batch
30 sec ExponentialBackoff Aantal nieuwe pogingen
Min. uitstel
Max. uitstel
Delta-uitstel
Eerste snelle poging
5
0 sec.
60 sec.
2 sec.
false
Poging 1, vertraging 0 sec.
Poging 2, vertraging ~2 sec.
Poging 3, vertraging ~6 sec.
Poging 4, vertraging ~14 sec.
Poging 5, vertraging ~30 sec.

Notitie

Voor de beoogde end-to-end-latentie wordt uitgegaan van de standaardtime-out voor verbindingen met de service. Als u langere verbindingstime-outs opgeeft, wordt de end-to-end-latentie uitgebreid met deze extra tijd voor elke nieuwe poging.

Voorbeelden

In deze sectie wordt beschreven hoe u Polly kunt gebruiken om toegang te krijgen tot Azure SQL Database met behulp van een set beleidsregels voor opnieuw proberen die zijn geconfigureerd in de klasse Policy.

De volgende code toont een uitbreidingsmethode op de klasse SqlCommand die ExecuteAsync aanroept met exponentieel uitstel.

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);
}

Deze asynchrone uitbreidingsmethode kan als volgt worden gebruikt.

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

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

Volgende stappen

SQL Database met Entity Framework 6

SQL Database is een gehoste SQL-database die beschikbaar is in allerlei afmetingen en zowel als standaardservice (gedeeld) en als premiumservice (niet gedeeld). Entity Framework is een object-relationele mapper waarmee .NET-ontwikkelaars kunnen werken met relationele gegevens met behulp van domeinspecifieke objecten. In dit geval is de meeste code voor gegevenstoegang die ontwikkelaars gewoonlijk moeten schrijven, niet meer nodig.

Mechanisme voor opnieuw proberen

Ondersteuning voor opnieuw proberen wordt geboden bij het openen van SQL Database met behulp van Entity Framework 6.0 en hoger via een mechanisme met de naam Verbinding maken ion resiliency/retry logic. De belangrijkste functies van het mechanisme voor opnieuw proberen zijn:

  • De primaire abstrahering is de interface IDbExecutionStrategy. Deze interface:
    • Definieert synchrone en asynchrone execute-methoden .
    • Definieert klassen die rechtstreeks kunnen worden gebruikt of kunnen worden geconfigureerd in een databasecontext als standaardstrategie of die kunnen worden toegewezen aan een providernaam of aan een providernaam en servernaam. Wanneer dit is geconfigureerd in een context, worden nieuwe pogingen uitgevoerd op het niveau van afzonderlijke databasebewerkingen, waarvan er mogelijk meerdere zijn voor een bepaalde contextbewerking.
    • Definieert wanneer moet worden geprobeerd een mislukte verbinding opnieuw tot stand te brengen en hoe.
  • Het bevat verschillende ingebouwde implementaties van de IDbExecutionStrategy-interface :
    • Standaard: geen nieuwe poging.
    • Standaardinstelling voor SQL Database (automatisch): geen nieuwe pogingen, maar inspecteert uitzonderingen en verpakt deze met suggesties voor het gebruik van de SQL Database-strategie.
    • Standaardinstelling voor SQL Database: exponentieel (overgenomen van basisklasse) plus detectielogica voor SQL Database.
  • Hiermee wordt een strategie voor exponentieel uitstel met willekeurige intervallen geïmplementeerd.
  • De ingebouwde klassen voor opnieuw proberen zijn stateful en zijn niet thread-safe. Ze kunnen echter opnieuw worden gebruikt nadat de huidige bewerking is voltooid.
  • Als het opgegeven aantal nieuwe pogingen wordt overschreden, worden de resultaten verpakt in een nieuwe uitzondering. De huidige uitzondering wordt niet opgebeld.

Beleidsconfiguratie

Ondersteuning voor nieuwe pogingen wordt geboden bij toegang tot SQL Database met behulp van Entity Framework 6.0 en hoger. Beleid voor opnieuw proberen wordt geconfigureerd via programmacode. De configuratie kan niet per bewerking worden gewijzigd.

Wanneer u een strategie in de context als standaard configureert, geeft u een functie op die een nieuwe strategie op aanvraag maakt. De volgende code laat zien hoe u een configuratieklasse voor opnieuw proberen maakt die de basisklasse DbConfiguration uitbreidt.

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)));
  }
}

U kunt deze vervolgens opgeven als de standaardstrategie voor opnieuw proberen voor alle bewerkingen met de methode SetConfiguration van het exemplaar van DbConfiguration wanneer de toepassing wordt gestart. Standaard detecteert en gebruikt EF de configuratieklasse.

DbConfiguration.SetConfiguration(new BloggingContextConfiguration());

U kunt de configuratieklasse voor opnieuw proberen voor een context opgeven door de contextklasse te voorzien van het kenmerk DbConfigurationType. Als u echter slechts één configuratieklasse hebt, gebruikt EF deze zonder de noodzaak om de context toe te voegen.

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

Als u andere strategieën voor opnieuw proberen moet gebruiken voor specifieke bewerkingen of als u nieuwe pogingen voor bepaalde bewerkingen wilt uitschakelen, kunt u een configuratieklasse maken waarmee u strategieën kunt onderbreken of afwisselen door een vlag te stellen in de CallContext. De configuratieklasse kan deze vlag gebruiken om tussen strategieën te schakelen of om de strategie die u opgeeft uit te schakelen en een standaardstrategie te gebruiken. Zie Uitvoeringsstrategie onderbreken (EF6 en hoger) voor meer informatie.

Een andere methode voor het gebruik van specifieke strategieën voor opnieuw proberen bestaat eruit een exemplaar van de vereiste strategieklasse te maken en de gewenste instellingen aan te leveren via parameters. Vervolgens start u de methode 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()
);

De eenvoudigste manier om de klasse DbConfiguration te gebruiken, is deze te zoeken in dezelfde assembly als de klasse DbContext. Dit is echter niet geschikt wanneer dezelfde context vereist is in verschillende scenario's, zoals verschillende interactieve strategieën en strategieën voor opnieuw proberen op de achtergrond. Als de verschillende contexten worden uitgevoerd in afzonderlijke toepassingsdomeinen, kunt u de ingebouwde ondersteuning voor het opgeven van configuratieklassen in het configuratiebestand gebruiken of deze expliciet instellen met behulp van code. Als de verschillende contexten moeten worden uitgevoerd in hetzelfde toepassingsdomein, is een aangepaste oplossing vereist.

Zie Op code gebaseerde configuratie (EF6 en hoger) voor meer informatie.

In de volgende tabel ziet u de standaardinstellingen voor het ingebouwde beleid voor opnieuw proberen bij gebruik van EF6.

Instelling Default value Betekenis
Beleid Exponentieel Exponentieel uitstel.
MaxRetryCount 5 Het maximum aantal nieuwe pogingen.
MaxDelay 30 seconden De maximale wachttijd tussen nieuwe pogingen. Deze waarde heeft geen invloed op de wijze waarop de reeks vertragingen wordt berekend. Deze definieert enkel een bovengrens.
DefaultCoefficient 1 seconde De coëfficiënt voor de berekening van het exponentiële uitstel. Deze waarde kan niet worden gewijzigd.
DefaultRandomFactor 1.1 De vermenigvuldigingsfactor die wordt gebruikt om een willekeurige vertraging voor elk item toe te voegen. Deze waarde kan niet worden gewijzigd.
DefaultExponentialBase 2 De vermenigvuldigingsfactor die wordt gebruikt om de volgende vertraging te berekenen. Deze waarde kan niet worden gewijzigd.

Gebruiksrichtlijnen voor opnieuw proberen

Houd rekening met de volgende richtlijnen wanneer u toegang hebt tot SQL Database met EF6:

  • Kies de juiste service-optie (gedeeld of premium). Een gedeeld exemplaar kan te maken krijgen met langere verbindingsvertragingen en meer beperkingen dan gebruikelijk is doordat andere tenants de gedeelde server gebruiken. Als voorspelbare prestaties en betrouwbare bewerkingen met een lage latentie zijn vereist, kunt u overwegen de premiumoptie te kiezen.

  • Een strategie met een vast interval wordt niet aanbevolen voor gebruik met Azure SQL Database. Gebruik in plaats daarvan een strategie voor exponentieel uitstel omdat de service overbelast zijn kan en langere vertragingen meer tijd voor herstel bieden.

  • Kies een geschikte waarde voor de time-outs voor verbinding en opdrachten bij het definiëren van verbindingen. Baseer de time-out zowel op het ontwerp van uw zakelijke logica als op tests. Mogelijk moet u deze waarde na verloop van tijd wijzigen als de gegevensvolumes of de bedrijfsprocessen veranderen. Een te korte time-out kan leiden tot voortijdige verbroken verbindingen wanneer de database bezet is. Een te lange time-out kan verhinderen dat de logica voor nieuwe pogingen correct werkt doordat te lang wordt gewacht voordat een mislukte verbinding wordt gedetecteerd. De waarde van de time-out is een onderdeel van de end-to-end latentie, hoewel u niet eenvoudig kunt bepalen hoeveel opdrachten worden uitgevoerd wanneer u de context opslaat. U kunt de standaardtime-out wijzigen door de eigenschap CommandTimeout van het exemplaar van DbContext in te stellen.

  • Entity Framework ondersteunt configuraties voor nieuwe pogingen die zijn gedefinieerd in configuratiebestanden. Voor een maximale flexibiliteit in Azure moet u echter overwegen de configuratie via de programmacode in de toepassing te maken. De specifieke parameters voor het beleid voor opnieuw proberen, zoals het aantal nieuwe pogingen en de intervallen hiertussen, kunnen worden opgeslagen in het configuratiebestand van de service en tijdens de uitvoering worden gebruikt om het juiste beleid te maken. Zo is het mogelijk dat de instellingen veranderen zonder dat de toepassing opnieuw moet worden opgestart.

Overweeg te beginnen met de volgende instellingen voor het opnieuw proberen van bewerkingen. U kunt de vertraging tussen nieuwe pogingen niet opgeven (dit is vast en gegenereerd als een exponentiële reeks). U kunt alleen de maximale waarden opgeven, zoals hier wordt weergegeven, tenzij u een aangepaste strategie voor opnieuw proberen maakt. Deze instellingen zijn algemeen gebruik en u moet de bewerkingen controleren en de waarden aanpassen aan uw eigen scenario.

Context Voorbeelddoel E2E
maximale latentie
Beleid voor opnieuw proberen Instellingen Waarden Hoe werkt het?
Interactief, UI
of voorgrond
2 seconden Exponentieel MaxRetryCount
MaxDelay
3
750 ms
Poging 1, vertraging 0 sec.
Poging 2, vertraging 750 ms
Poging 3, vertraging 750 ms
Achtergrond
of batch
30 seconden Exponentieel MaxRetryCount
MaxDelay
5
12 seconden
Poging 1, vertraging 0 sec.
Poging 2, vertraging ~1 sec.
Poging 3, vertraging ~3 sec.
Poging 4, vertraging ~7 sec.
Poging 5, vertraging ~12 sec.

Notitie

Voor de beoogde end-to-end-latentie wordt uitgegaan van de standaardtime-out voor verbindingen met de service. Als u langere verbindingstime-outs opgeeft, wordt de end-to-end-latentie uitgebreid met deze extra tijd voor elke nieuwe poging.

Voorbeelden

Het volgende codevoorbeeld definieert een eenvoudige oplossing voor gegevenstoegang die gebruikmaakt van Entity Framework. Er wordt een specifieke strategie voor opnieuw proberen ingesteld door een exemplaar van een klasse genaamd BlogConfiguration te definiëren die DbConfiguration uitbreidt.

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();
            }
        }
    }
}

Meer voorbeelden van het gebruik van het Entity Framework-mechanisme voor opnieuw proberen vindt u in Verbinding maken ietolerantie/ pogingslogica.

SQL Database met Entity Framework Core

Entity Framework Core is een object-relationele mapper waarmee .NET Core-ontwikkelaars kunnen werken met gegevens met behulp van domeinspecifieke objecten. In dit geval is de meeste code voor gegevenstoegang die ontwikkelaars gewoonlijk moeten schrijven, niet meer nodig. Deze versie van Entity Framework is helemaal opnieuw geschreven en neemt niet automatisch alle functies van EF6.x over.

Mechanisme voor opnieuw proberen

Ondersteuning voor opnieuw proberen wordt geboden bij het openen van SQL Database met behulp van Entity Framework Core via een mechanisme dat verbindingstolerantie wordt genoemd. Verbindingstolerantie is geïntroduceerd in EF Core 1.1.0.

De primaire abstrahering is de interface IExecutionStrategy. De uitvoeringsstrategie voor SQL Server, inclusief SQL Azure, is op de hoogte van de typen uitzonderingen die opnieuw kunnen worden geprobeerd en heeft praktische standaardinstellingen voor het maximum aantal nieuwe pogingen, de vertraging tussen pogingen enzovoort.

Voorbeelden

De volgende code maakt automatische nieuwe pogingen mogelijk bij de configuratie van het object DbContext, dat een sessie met de database vertegenwoordigt.

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

De volgende code laat zien hoe u een transactie met automatische nieuwe pogingen uitvoert met behulp van een uitvoeringsstrategie. De transactie is gedefinieerd in een gemachtigde. Als er een tijdelijke fout optreedt, roept de uitvoeringsstrategie de gemachtigde opnieuw aan.

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();
        }
    });
}

Azure Storage

Azure Storage-services omvatten blobopslag, bestanden en opslagwachtrijen.

Blobs, wachtrijen en bestanden

De ClientOptions-klasse is het basistype voor alle clientoptietypen en biedt verschillende algemene clientopties, zoals Diagnostische gegevens, Opnieuw proberen, Transport. Als u de clientconfiguratieopties wilt bieden voor het maken van verbinding met Azure Queue, Blob en File Storage, moet u het bijbehorende afgeleide type gebruiken. In het volgende voorbeeld gebruikt u de klasse QueueClientOptions (afgeleid van ClientOptions) om een client te configureren om verbinding te maken met Azure Queue Service. De eigenschap Opnieuw proberen is de set opties die kunnen worden opgegeven om te beïnvloeden hoe nieuwe pogingen worden gedaan en hoe een fout in aanmerking komt om opnieuw te worden geprobeerd.

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

Ondersteuning voor tabellen

Notitie

WindowsAzure.Storage Nuget Package en Microsoft.Azure.Cosmos.Table Nuget Package zijn afgeschaft. Zie Azure.Data.Tables Nuget Package voor ondersteuning voor Azure-tabellen

Mechanisme voor opnieuw proberen

De clientbibliotheek is gebaseerd op een Azure Core-bibliotheek, een bibliotheek die geavanceerde services aan andere clientbibliotheken biedt.

Er zijn veel redenen waarom fouten kunnen optreden wanneer een clienttoepassing probeert een netwerkaanvraag naar een service te verzenden. Enkele voorbeelden zijn time-outs, netwerkinfrastructuurfouten, service die de aanvraag weigert vanwege vertraging/bezet, het beëindigen van het service-exemplaar vanwege omlaag schalen van de service, het service-exemplaar wordt vervangen door een andere versie, service loopt vast vanwege een niet-verwerkte uitzondering, enzovoort. Door een ingebouwd mechanisme voor opnieuw proberen aan te bieden (met een standaardconfiguratie die de consument kan overschrijven), worden onze SDK's en de toepassing van de consument bestand tegen dergelijke fouten. Houd er rekening mee dat sommige services echt geld in rekening brengen voor elke aanvraag, zodat consumenten de nieuwe pogingen volledig kunnen uitschakelen als ze liever geld besparen op tolerantie.

Beleidsconfiguratie

Beleid voor opnieuw proberen wordt geconfigureerd via programmacode. De configuratie is gebaseerd op de klasse RetryOption. Er is een kenmerk voor TableClientOptions overgenomen van ClientOptions

      var tableClientOptions = new TableClientOptions();
      tableClientOptions.Retry.Mode = RetryMode.Exponential;
      tableClientOptions.Retry.MaxRetries = 5;
      var serviceClient = new TableServiceClient(connectionString, tableClientOptions);

In de volgende tabellen ziet u de mogelijkheden voor het ingebouwde beleid voor opnieuw proberen.

RetryOption

Instelling Betekenis
Vertraging De vertraging tussen nieuwe pogingen voor een vaste benadering of de vertraging waarop berekeningen voor een back-off-gebaseerde benadering moeten worden gebaseerd. Als de service een header Voor opnieuw proberen na antwoord biedt, wordt de volgende nieuwe poging uitgesteld door de duur die is opgegeven door de headerwaarde.
MaxDelay De maximaal toegestane vertraging tussen nieuwe pogingen wanneer de service geen header voor opnieuw proberen biedt. Als de service een header Voor opnieuw proberen na antwoord biedt, wordt de volgende nieuwe poging uitgesteld door de duur die is opgegeven door de headerwaarde.
Modus De methode die moet worden gebruikt voor het berekenen van vertragingen voor opnieuw proberen.
NetworkTimeout De time-out die is toegepast op afzonderlijke netwerkbewerkingen.

RetryMode

Instelling Betekenis
Exponentieel Nieuwe pogingen worden vertraagd op basis van een back-offstrategie, waarbij elke poging de duur verhoogt die wordt gewacht voordat het opnieuw wordt geprobeerd.
MaxDelay Nieuwe pogingen gebeuren met vaste intervallen; elke vertraging is een consistente duur.

Telemetrie

De eenvoudigste manier om de logboeken te bekijken, is door consolelogboekregistratie in te schakelen. Als u een Azure SDK-logboeklistener wilt maken die berichten naar de console uitvoert, gebruikt u de methode AzureEventSourceListener.CreateConsoleLogger.

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

Voorbeelden

Door het volgende codevoorbeeld uit te voeren waarbij de opslagemulator wordt afgesloten, kunnen we informatie bekijken over nieuwe pogingen in de console.

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

namespace RetryCodeSamples
{
    class AzureStorageCodeSamples
    {
        private const string connectionString = "UseDevelopmentStorage=true";
        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(connectionString, tableClientOptions);

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

Algemene richtlijnen voor REST en opnieuw proberen

Houd rekening met het volgende bij het openen van Azure- of services van derden:

  • Gebruik een systematische aanpak voor het beheer van nieuwe pogingen, mogelijk als herbruikbare code, zodat u een consistente methodologie kunt toepassen voor alle clients en alle oplossingen.

  • Overweeg het gebruik van een framework voor opnieuw proberen, zoals Polly , om nieuwe pogingen te beheren als de doelservice of client geen ingebouwd mechanisme voor opnieuw proberen heeft. Dit helpt u een consistent gedrag voor opnieuw proberen te implementeren en kan een geschikte strategie voor de doelservice zijn. Mogelijk moet u echter aangepaste code voor opnieuw proberen maken voor services met niet-standaardgedrag dat niet afhankelijk is van uitzonderingen om tijdelijke fouten aan te geven of als u een antwoord voor opnieuw proberen wilt gebruiken om gedrag voor opnieuw proberen te beheren.

  • De tijdelijke detectielogica is afhankelijk van de daadwerkelijke client-API die u gebruikt voor de REST-aanroepen. Sommige clients, zoals de nieuwere HttpClient-klasse , genereren geen uitzonderingen voor voltooide aanvragen met een HTTP-statuscode zonder succes.

  • De HTTP-statuscode die door de service wordt geretourneerd, kan aangeven of de fout tijdelijk is. Mogelijk moet u de uitzonderingen die worden gegenereerd door een client of het framework onderzoeken om toegang te krijgen tot de statuscode of om het equivalente type uitzondering te bepalen. De volgende HTTP-codes geven meestal aan dat een nieuwe poging toepasselijke is:

    • 408 Time-out van aanvraag
    • 429 Te veel aanvragen
    • 500 Interne serverfout
    • 502 Ongeldige gateway
    • 503 Service niet beschikbaar
    • 504 Time-out van gateway
  • Als u uw logica voor nieuwe pogingen baseert op uitzonderingen, geeft het volgende doorgaans een tijdelijke fout aan als er geen verbinding tot stand kan worden gebracht:

    • WebExceptionStatus.ConnectionClosed
    • WebExceptionStatus.ConnectFailure
    • WebExceptionStatus.Timeout
    • WebExceptionStatus.RequestCanceled
  • In het geval dat de status van een service niet beschikbaar is, kan de service de juiste vertraging voordat het opnieuw wordt geprobeerd, aangeven in de antwoordheader Retry-After of een andere aangepaste header. Services kunnen aanvullende informatie ook verzenden als aangepaste headers of ingesloten in de inhoud van de reactie.

  • Probeer het niet opnieuw voor statuscodes die clientfouten (fouten in het bereik 4xx) vertegenwoordigen, met uitzondering van een time-out voor 408 aanvragen en 429 Te veel aanvragen.

  • Test uw strategieën en mechanismen voor opnieuw proberen grondig in allerlei omstandigheden, zoals verschillende netwerkstatussen en wisselende systeembelastingen.

Strategieën voor opnieuw proberen

De volgende zijn standaardsoorten intervallen voor strategieën voor opnieuw proberen:

  • Exponentieel. Een beleid voor opnieuw proberen dat een opgegeven aantal nieuwe pogingen uitvoert, met behulp van een gerandomiseerde exponentiële uitstelbenadering om het interval tussen nieuwe pogingen te bepalen. Voorbeeld:

    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);
    
  • Incrementeel. Een strategie voor opnieuw proberen met een opgegeven aantal nieuwe pogingen en een incrementeel tijdsinterval tussen nieuwe pogingen. Voorbeeld:

    retryInterval = TimeSpan.FromMilliseconds(this.initialInterval.TotalMilliseconds +
                    (this.increment.TotalMilliseconds * currentRetryCount));
    
  • LinearRetry. Een beleid voor opnieuw proberen dat een opgegeven aantal nieuwe pogingen uitvoert, met behulp van een opgegeven vast tijdsinterval tussen nieuwe pogingen. Voorbeeld:

    retryInterval = this.deltaBackoff;
    

Tijdelijke fouten afhandelen met Polly

Polly is een bibliotheek voor het programmatisch afhandelen van nieuwe pogingen en circuitonderbrekerstrategieën . Het Polly-project maakt deel uit van de .NET Foundation. Voor services waarbij de client geen systeemeigen ondersteuning biedt voor nieuwe pogingen, is Polly een geldig alternatief en voorkomt u dat u aangepaste code voor opnieuw proberen hoeft te schrijven, wat moeilijk te implementeren is. Polly biedt ook een manier om fouten te traceren wanneer deze zich voordoen, zodat u nieuwe pogingen kunt vastleggen.

Volgende stappen