Vägledning för återförsök för Azure-tjänster
De flesta Azure-tjänster och klient-SDK:er har en återförsöksmekanism. Med dessa skiljer sig eftersom varje tjänst har olika egenskaper, så varje återförsöksmekanism justeras efter en specifik tjänst. I den här guiden sammanfattas återförsöksmekanismerna för majoriteten av Azure-tjänsterna och innehåller information som hjälper dig att använda, anpassa eller utöka återförsöksmekanismen för den tjänsten.
För allmänna råd om hanteringen av tillfälliga fel, och om återförsök av anslutningar och åtgärder mot tjänster och resurser, finns i Vägledning för återförsök.
I följande tabell sammanfattas återförsöksfunktionerna för de Azure-tjänster som beskriva i den här vägledningen.
| Tjänst | Återförsöksfunktioner | Principkonfiguration | Omfång | Telemetrifunktioner |
|---|---|---|---|---|
| Azure Active Directory | Inbyggt i MSAL-bibliotek | Inbäddat i MSAL-bibliotek | Intern | Ingen |
| Cosmos DB | Inbyggd i tjänsten | Inte konfigurerbar | Global | TraceSource |
| Data Lake Store | Inbyggd i klienten | Inte konfigurerbar | Enskilda åtgärder | Ingen |
| Event Hubs | Inbyggd i klienten | Programmässig | Client | Ingen |
| IoT Hub | Inbyggd i klient-SDK | Programmässig | Client | Ingen |
| Azure Cache for Redis | Inbyggd i klienten | Programmässig | Client | TextWriter |
| Sök | Inbyggd i klienten | Programmässig | Client | ETW eller anpassad |
| Service Bus | Inbyggd i klienten | Programmässig | Namespace Manager, Messaging Factory och Client | ETW |
| Service Fabric | Inbyggd i klienten | Programmässig | Client | Ingen |
| SQL Database med ADO.NET | Polly | Deklarativ och programmässig | Enskilda instruktioner eller kodblock | Anpassat |
| SQL Database med Entity Framework | Inbyggd i klienten | Programmässig | Global per AppDomain | Ingen |
| SQL Database med Entity Framework Core | Inbyggd i klienten | Programmässig | Global per AppDomain | Ingen |
| Storage | Inbyggd i klienten | Programmässig | Klientåtgärder och enskilda åtgärder | TraceSource |
Anteckning
För de flesta inbyggda återförsöksmekanismer i Azure finns det för närvarande inget sätt att tillämpa en annan återförsöksprincip för olika typer av fel eller undantag. Du bör konfigurera en princip som ger optimala genomsnittliga prestanda och tillgänglighet. Ett sätt att finjustera principen är att analysera loggfiler för att fastställa den typ av tillfälliga fel som inträffar.
Azure Active Directory
Azure Active Directory är en omfattande molnlösning för identitets- och åtkomsthantering som kombinerar kärnkatalogstjänster, avancerad identitetsstyrning, säkerhet och programåtkomsthantering. Azure AD erbjuder dessutom utvecklare en plattform för identitetshantering som ger åtkomstkontroll till deras program, baserat på centraliserade principer och regler.
Anteckning
Mer information om slutpunkter för hanterad tjänstidentitet finns i Så här använder du en hanterad tjänstidentitet (MSI) för en virtuell Azure-dator för tokenförvärv.
Återförsöksmekanism
Det finns en inbyggd återförsöksmekanism för Azure Active Directory i Microsoft Authentication Library (MSAL). För att undvika oväntade utelåsningar rekommenderar vi att bibliotek från tredje part och programkod inte försöker igen med misslyckade anslutningar, men låter MSAL hantera återförsök.
Vägledning för återförsöksanvändning
Tänk på följande när du använder Azure Active Directory:
- När det är möjligt använder du MSAL-biblioteket och det inbyggda stödet för återförsök.
- Om du använder REST API för Azure Active Directory försöker du igen om resultatkoden är 429 (för många begäranden) eller ett fel i 5xx-intervallet. Gör inga nya försök för andra fel.
- För 429-fel försöker du bara igen efter den tid som anges i rubriken Retry-After.
- För 5xx-fel använder du exponentiell back-off, med det första återförsöket minst 5 sekunder efter svaret.
- Försök inte igen med andra fel än 429 och 5xx.
Mer information
Cosmos DB
Cosmos DB är en fullständigt hanterad databas med flera modeller som stöder schemalösa JSON-data. Det erbjuder konfigurerbar och pålitlig drift, den har inbyggd transaktionsbehandling med JavaScript och den är byggd för molnet med elastisk skala.
Återförsöksmekanism
Klassen CosmosClient gör automatiskt om misslyckade försök. Om du vill ange antalet återförsök och den maximala väntetiden konfigurerar du CosmosClientOptions. Undantag som klienten aktiverar ligger utanför återförsöksprincipen eller är inte tillfälliga fel.
Om Cosmos DB begränsar klienten returneras ett HTTP 429-fel. Kontrollera statuskoden i CosmosException klassen .
Principkonfiguration
I följande tabell visas standardinställningarna för klassen CosmosClientOptions.
| Inställning | Standardvärde | Beskrivning |
|---|---|---|
| MaxRetryAttemptsOnRateLimitedRequests | 9 | Det maximala antalet försök om begäran misslyckas för att Cosmos DB tillämpar hastighetsbegränsning på klienten. |
| MaxRetryWaitTimeOnRateLimitedRequests | 30 | Den maximala återförsökstiden i sekunder för den Azure Cosmos DB tjänsten. |
Exempel
CosmosClient cosmosClient = new CosmosClient("connection-string", new CosmosClientOptions()
{
MaxRetryAttemptsOnRateLimitedRequests = 5,
MaxRetryWaitTimeOnRateLimitedRequests = TimeSpan.FromSeconds(15)
});
Telemetri
Försöken loggas som ostrukturerade spårningsmeddelanden genom en .NET TraceSource. Du måste konfigurera en TraceListener för att registrera händelserna och skriva dem till en lämplig mållogg.
Om du till exempel lägger till följande i App.config-filen genereras spårningar i en textfil på samma plats som den körbara filen:
<configuration>
<system.diagnostics>
<switches>
<add name="SourceSwitch" value="Verbose"/>
</switches>
<sources>
<source name="DocDBTrace" switchName="SourceSwitch" switchType="System.Diagnostics.SourceSwitch" >
<listeners>
<add name="MyTextListener" type="System.Diagnostics.TextWriterTraceListener" traceOutputOptions="DateTime,ProcessId,ThreadId" initializeData="CosmosDBTrace.txt"></add>
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
Event Hubs
Azure Event Hubs är en telemetriinmatningstjänst i hyperskala som samlar in, transformerar och lagrar miljontals händelser.
Återförsöksmekanism
Återförsöksbeteende i Azure Event Hubs-klientbiblioteket styrs av egenskapen RetryPolicy i klassen EventHubClient. Standardprincipen gör nya försök med exponentiell backoff när Azure Event Hub returnerar ett tillfälligt EventHubsException eller OperationCanceledException. Standardprincipen för återförsök för Event Hubs är att försöka igen upp till 9 gånger med en exponentiell back-off-tid på upp till 30 sekunder.
Exempel
EventHubClient client = EventHubClient.CreateFromConnectionString("[event_hub_connection_string]");
client.RetryPolicy = RetryPolicy.Default;
Mer information
.NET Standard-klientbibliotek för Azure Event Hubs
IoT Hub
Azure IoT Hub är en tjänst för att ansluta, övervaka och hantera enheter för att utveckla Sakernas Internet -program (IoT).
Återförsöksmekanism
Sdk för Azure IoT-enheter kan identifiera fel i nätverket, protokollet eller programmet. Baserat på feltypen kontrollerar SDK om ett nytt försök måste utföras. Om felet kan återställas börjarSDK:n att försöka igen med hjälp av den konfigurerade återförsöksprincipen.
Standardprincipen för återförsök är exponentiell back-off med slumpmässig jitter,men den kan konfigureras.
Principkonfiguration
Principkonfigurationen skiljer sig åt efter språk. Mer information finns i IoT Hub återförsöksprincipkonfiguration.
Mer information
Azure Cache for Redis
Azure Cache for Redis är en snabb dataåtkomst och cachetjänst med låg latens som baseras på den populära Redis-cachen med öppen källkod. Den är säker, hanteras av Microsoft och går att nå från alla program i Azure.
Vägledningen i det här avsnittet baseras på att StackExchange.Redis-klienten används för åtkomst till cachen. En lista över passande klienter finns på Redis-webbplatsen och de kan ha olika återförsöksmekanismer.
Obs! StackExchange.Redis-klienten använder multiplexering genom en enda anslutning. Den rekommenderade användningen är att skapa en instans av klienten vid programstart och använda denna instans för alla åtgärder mot cachen. Av den anledningen görs anslutningen till cachen bara en gång, så alla råd i det här avsnittet är relaterade till återförsöksprincipen för denna första anslutningen – och inte för varje åtgärd som använder cachen.
Återförsöksmekanism
StackExchange.Redis-klienten använder en anslutningshanterare-klass som konfigureras via en uppsättning alternativ, inklusive:
- ConnectRetry. Antalet gånger som nya försök görs att upprätta en anslutning som misslyckats.
- ReconnectRetryPolicy. Återförsöksstrategin som ska användas.
- ConnectTimeout. Maximal väntetid i millisekunder.
Principkonfiguration
Återförsöksprinciper konfigureras programmässigt genom att ange alternativen för klienten innan du ansluter till cachen. Detta kan göras genom att skapa en instans av klassen ConfigurationOptions, fylla i dess egenskaper och skicka den till metoden Connect.
Den inbyggda klasserna stöder linjär (konstant) fördröjning och exponentiell backoff med slumpmässiga återförsöksintervall. Du kan också skapa en egen återförsöksprincip genom att implementera gränssnittet IReconnectRetryPolicy.
I följande exempel konfigureras en återförsöksstrategi med exponentiell backoff.
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);
Alternativt kan du ange alternativen som en sträng och skicka den till metoden Connect. Egenskapen ReconnectRetryPolicy kan inte anges på det här sättet, endast via kod.
var options = "localhost,connectRetry=3,connectTimeout=2000";
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);
Du kan också ange alternativ direkt när du ansluter till cachen.
var conn = ConnectionMultiplexer.Connect("redis0:6380,redis1:6380,connectRetry=3");
Med information finns i Stack Exchange Redis Configuration i StackExchange.Redis-dokumentationen.
Följande tabell visar standardinställningarna för den inbyggda återförsöksprincipen.
| Kontext | Inställning | Standardvärdet (v 1.2.2) |
Innebörd |
|---|---|---|---|
| ConfigurationOptions | ConnectRetry ConnectTimeout SyncTimeout ReconnectRetryPolicy |
3 Max. 5 000 ms plus SyncTimeout 1000 LinearRetry 5 000 ms |
Antalet gånger som anslutningsförsöken upprepas under den första anslutningen. Timeout (ms) för anslutningsåtgärder. Ingen fördröjning mellan försöken. Tid (ms) som tillåts för synkrona åtgärder. Nytt försök var 5 000 ms. |
Anteckning
För synkrona åtgärder kan SyncTimeout lägga till svarstiden för slutpunkt till slutpunkt, men ett för lågt värde kan orsaka långa timeouter. Se Så här felsöker du Azure Cache for Redis. Allmänt sett bör du undvika synkrona åtgärder och istället använda asynkrona åtgärder. Mer information finns i Pipelines och Multiplexers.
Vägledning för återförsöksanvändning
Tänk på följande när du använder Azure Cache for Redis:
- StackExchange Redis-klienten hanterar sina egna återförsök men bara när en anslutning upprättas till cachen när programmet först startar. Du kan konfigurera anslutningstimeouten, antalet återförsök och tiden mellan försöken för att upprätta anslutningen men återförsöksprincipen gäller inte för åtgärder mot cachen.
- Istället för att använda ett stort antal försök kan du återgå genom att komma åt den ursprungliga datakällan istället.
Telemetri
Du kan samla in information om anslutningar (men inga andra åtgärder) med en TextWriter.
var writer = new StringWriter();
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);
Ett exempel på vilka utdata detta genererar visas nedan.
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...
...
Exempel
Följande kodexempel konfigurerar en konstant (linjär) fördröjning mellan försök vid initiering av StackExchange.Redis-klienten. I det här exemplet visas hur du anger konfigurationen med en ConfigurationOptions-instans.
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;
}
}
}
}
}
Nästa exempel anger konfigurationen genom att ange alternativen som en sträng. Anslutningstimeouten är den maximala väntetiden för en anslutning till cachen, inte fördröjningen mellan försök. Obs! egenskapen ReconnectRetryPolicy kan bara anges med kod.
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;
}
}
}
}
}
Fler exempel finns i Konfiguration på projektwebbplatsen.
Mer information
Azure Search
Azure Search kan användas till att lägga till kraftfulla och avancerade sökfunktioner på en webbplats eller i ett program, snabbt och enkelt justera sökresultat och skapa omfattande och finjusterade rankningsmodeller.
Återförsöksmekanism
Återförsöksbeteendet i Azure Search SDK styrs av metoden SetRetryPolicy för klasserna SetRetryPolicy och SearchIndexClient. Standardprincipen gör försök med exponentiell backoff när Azure Search returnerar svaret 5xx eller 408 (timeout för begäran).
Telemetri
Spåra med ETW eller genom att registrera en anpassad spårningsprovider. Mer information finns i AutoRest-dokumentationen.
Service Bus
Service Bus är en molnmeddelandeplattform som ger ett löst sammankopplat meddelandeutbyte med förbättrad skala och återhämtning för komponenter för ett program, oavsett om den finns i molnet eller lokalt.
Återförsöksmekanism
Service Bus implementerar återförsök med hjälp av implementeringar av den abstrakta RetryPolicy-klassen. Namnområdet och en del av konfigurationsinformationen beror på Service Bus klient-SDK-paketet används:
| Paket | Beskrivning | Namnområde |
|---|---|---|
| Microsoft.Azure.ServiceBus | Azure Service Bus klientbibliotek för .NET Standard. | Microsoft.ServiceBus |
| WindowsAzure.ServiceBus | Det här paketet är det Service Bus klientbiblioteket. Det kräver .NET Framework 4.5.2. | Microsoft.Azure.ServiceBus |
Båda versionerna av klientbiblioteket innehåller följande inbyggda implementeringar av RetryPolicy :
RetryExponential. Implementerar exponentiell backoff.
NoRetry. Utför inte återförsök. Använd den här klassen när du inte behöver återförsök på API-nivån Service Bus, till exempel när en annan process hanterar återförsök som en del av en batch- eller flerstegsåtgärd.
Egenskapen RetryPolicy.Default returnerar en standardprincip av typen RetryExponential . Det här principobjektet har följande inställningar:
| Inställning | Standardvärde | Innebörd |
|---|---|---|
| MinimalBackoff | 0 | Minsta backoffintervall. Har lagts till i återförsöksintervallet som beräknas från deltaBackoff . |
| MaximumBackoff | 30 sekunder | Högsta backoffintervall. |
| DeltaBackoff | 3 sekunder | Backoffintervall mellan återförsök. Multiplar av det här tidsspann används för efterföljande återförsök. |
| MaxRetryCount | 5 | Max. antal återförsök. (Standardvärdet är 10 i WindowsAzure.ServiceBus paketet.) |
Dessutom definieras följande egenskap i det äldre WindowsAzure.ServiceBus paketet:
| Inställning | Standardvärde | Innebörd |
|---|---|---|
| TerminationTimeBuffer | 5 sekunder | Återförsök avbryts om den återstående tiden är mindre än det här värdet. |
Service Bus åtgärder kan returnera ett antal undantag som anges i Service Bus undantag för meddelanden. Undantag som returneras Service Bus exponerar egenskapen IsTransient som anger om klienten ska försöka utföra åtgärden igen. Den inbyggda RetryExponential-principen kontrollerar den här egenskapen innan ett nytt försök görs.
Om det senaste undantaget var ServerBusyExceptionlägger RetryExponential-principen till 10 sekunder till det beräknade återförsöksintervallet. Värdet kan inte ändras.
Anpassade implementeringar kan använda en kombination av undantagstypen och egenskapen IsTransient för att ge mer kontroll över återförsöksåtgärder. Du kan till exempel identifiera ett QuotaExceededException och vidta åtgärd för att tömma kön innan du försöker skicka ett meddelande till den igen.
Följande kod anger återförsöksprincipen på en Service Bus klient med hjälp av Microsoft.Azure.ServiceBus biblioteket :
const string QueueName = "queue1";
const string ServiceBusConnectionString = "<your_connection_string>";
var policy = new RetryExponential(
minimumBackoff: TimeSpan.FromSeconds(10),
maximumBackoff: TimeSpan.FromSeconds(30),
maximumRetryCount: 3);
var queueClient = new QueueClient(ServiceBusConnectionString, QueueName, ReceiveMode.PeekLock, policy);
Återförsöksprincipen kan inte anges för enskilda åtgärder. Den gäller för alla åtgärder för klienten.
Vägledning för återförsöksanvändning
Tänk på följande när du använder Service Bus:
- När du använder den inbyggda RetryExponential-implementeringen ska du inte implementera en återställningsåtgärd eftersom principen reagerar på undantag för upptagen server och automatiskt byter till ett lämpligt återförsöksläge.
- Service Bus stöder en funktion som kallas parkopplade namnrymder som implementerar automatisk redundans till en säkerhetskopieringskö i ett separat namnområde om kön i det primära namnområdet misslyckas. Meddelanden från den sekundära kön kan skickas tillbaka till den primära kön när den återställs. Funktionen hjälper till att hantera tillfälliga fel. Mer information finns i Asynkrona meddelandemönster och hög tillgänglighet.
Överväg att börja med följande inställningar för återförsöksåtgärderna. De här inställningarna är generella och du bör övervaka åtgärderna och finjustera värdena så att de passar ditt eget scenario.
| Kontext | Exempel på maximal fördröjning | Återförsöksprincip | Inställningar | Så här fungerar det |
|---|---|---|---|---|
| Interaktiv, gränssnitt eller förgrund | 2 sekunder* | Exponentiellt | MinimumBackoff = 0 MaximumBackoff = 30 sek. DeltaBackoff = 300 ms. TimeBuffer = 300 ms. MaxRetryCount = 2 |
Försök 1: 0 sek. fördröjning Försök 2: ~300 ms. fördröjning Försök 3: ~900 ms. fördröjning |
| Bakgrund eller batch | 30 sekunder | Exponentiellt | MinimumBackoff = 1 MaximumBackoff = 30 sek. DeltaBackoff = 1,75 sek. TimeBuffer = 5 sek. MaxRetryCount = 3 |
Försök 1: ~1 sek. fördröjning Försök 2: ~3 sek. fördröjning Försök 3: ~6 sek. fördröjning Försök 4: ~13 sek. fördröjning |
* Inkluderar inte ytterligare fördröjning som läggs till om ett svar på servern är upptagen tas emot.
Telemetri
Service Bus loggar återförsök som ETW-händelser med EventSource. Du måste koppla en EventListener till händelsekällan för att registrera händelserna och visa dem i prestandavisningen eller skriva dem till lämplig mållogg. Återförsökshändelserna har följande format:
Microsoft-ServiceBus-Client/RetryPolicyIteration
ThreadID="14,500"
FormattedMessage="[TrackingId:] RetryExponential: Operation Get:https://retry-tests.servicebus.windows.net/TestQueue/?api-version=2014-05 at iteration 0 is retrying after 00:00:00.1000000 sleep because of Microsoft.ServiceBus.Messaging.MessagingCommunicationException: The remote name could not be resolved: 'retry-tests.servicebus.windows.net'.TrackingId:6a26f99c-dc6d-422e-8565-f89fdd0d4fe3, TimeStamp:9/5/2014 10:00:13 PM."
trackingId=""
policyType="RetryExponential"
operation="Get:https://retry-tests.servicebus.windows.net/TestQueue/?api-version=2014-05"
iteration="0"
iterationSleep="00:00:00.1000000"
lastExceptionType="Microsoft.ServiceBus.Messaging.MessagingCommunicationException"
exceptionMessage="The remote name could not be resolved: 'retry-tests.servicebus.windows.net'.TrackingId:6a26f99c-dc6d-422e-8565-f89fdd0d4fe3,TimeStamp:9/5/2014 10:00:13 PM"
Exempel
I följande exempelkod visar hur du anger återförsöksprincipen för:
- en namnrymdshanterare. Principen gäller för alla åtgärder för den hanteraren och kan inte åsidosättas för enskilda åtgärder.
- en meddelandefabrik. Principen gäller för alla klienter som skapats från den fabriken och kan inte åsidosättas när du skapar enskilda klienter.
- en enskild meddelandeklient. När en klient har skapats kan du ange återförsöksprincipen för den klienten. Principen gäller för alla åtgärder på den klienten.
using System;
using System.Threading.Tasks;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
namespace RetryCodeSamples
{
class ServiceBusCodeSamples
{
private const string connectionString =
@"Endpoint=sb://[my-namespace].servicebus.windows.net/;
SharedAccessKeyName=RootManageSharedAccessKey;
SharedAccessKey=C99..........Mk=";
public async static Task Samples()
{
const string QueueName = "TestQueue";
ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.Http;
var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
// The namespace manager will have a default exponential policy with 10 retry attempts
// and a 3 second delay delta.
// Retry delays will be approximately 0 sec, 3 sec, 9 sec, 25 sec and the fixed 30 sec,
// with an extra 10 sec added when receiving a ServiceBusyException.
{
// Set different values for the retry policy, used for all operations on the namespace manager.
namespaceManager.Settings.RetryPolicy =
new RetryExponential(
minBackoff: TimeSpan.FromSeconds(0),
maxBackoff: TimeSpan.FromSeconds(30),
maxRetryCount: 3);
// Policies cannot be specified on a per-operation basis.
if (!await namespaceManager.QueueExistsAsync(QueueName))
{
await namespaceManager.CreateQueueAsync(QueueName);
}
}
var messagingFactory = MessagingFactory.Create(
namespaceManager.Address, namespaceManager.Settings.TokenProvider);
// The messaging factory will have a default exponential policy with 10 retry attempts
// and a 3 second delay delta.
// Retry delays will be approximately 0 sec, 3 sec, 9 sec, 25 sec and the fixed 30 sec,
// with an extra 10 sec added when receiving a ServiceBusyException.
{
// Set different values for the retry policy, used for clients created from it.
messagingFactory.RetryPolicy =
new RetryExponential(
minBackoff: TimeSpan.FromSeconds(1),
maxBackoff: TimeSpan.FromSeconds(30),
maxRetryCount: 3);
// Policies cannot be specified on a per-operation basis.
var session = await messagingFactory.AcceptMessageSessionAsync();
}
{
var client = messagingFactory.CreateQueueClient(QueueName);
// The client inherits the policy from the factory that created it.
// Set different values for the retry policy on the client.
client.RetryPolicy =
new RetryExponential(
minBackoff: TimeSpan.FromSeconds(0.1),
maxBackoff: TimeSpan.FromSeconds(30),
maxRetryCount: 3);
// Policies cannot be specified on a per-operation basis.
var session = await client.AcceptMessageSessionAsync();
}
}
}
}
Mer information
Service Fabric
Distribution av pålitliga tjänster i ett Service Fabric-kluster skyddar mot de flesta potentiella tillfälliga fel som diskuteras i den här artikeln. Men vissa tillfälliga fel är fortfarande möjliga. Till exempel kan namngivningstjänsten vara mitt i en routningsändring när den får en begäran, vilket gör att den utlöser ett undantag. Om samma begäran kommer 100 millisekunder senare lyckas den troligen.
Internt hanterar Service Fabric denna typ av tillfälligt fel. Du kan konfigurera vissa inställningar genom att använda klassen OperationRetrySettings när du konfigurerar dina tjänster. Följande kod visar ett exempel. I de flesta fall bör detta inte vara nödvändigt och standardinställningarna räcker.
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));
Mer information
SQL Database med ADO.NET
SQL Database är en värdbaserad SQL-databas som finns i flera olika storlekar och som både standardtjänst (delad) och premiumtjänst (inte delad).
Återförsöksmekanism
SQL Database har inget inbyggt stöd för återförsök vid åtkomst med ADO.NET. Men returkoderna från begäranden kan användas till att fastställa varför en begäran har misslyckats. Mer information om SQL Database-begränsning finns i Resursbegränsningar för Azure SQL Database. En lista med relevanta felkoder finns i SQL-felkoder för SQL Database-klientprogram.
Du kan använda Polly-biblioteket till att implementera återförsök för SQL Database. Se Hantering av tillfälliga fel med Polly.
Vägledning för återförsöksanvändning
Tänk på följande när du använder SQL Database med ADO.NET:
- Välj lämplig tjänst (delad eller premium). En delad instans kan drabbas av längre anslutningsfördröjningar än normalt och nätverksbegränsningar på grund av andra klientorganisationers användning av den delade servern. Om fler förutsägbara prestanda och tillförlitliga åtgärder med låg latens krävs kan du överväga att använda premiumalternativet.
- Se till att du utför återförsök på rätt nivå eller med rätt omfattning för att undvika icke-idempotenta åtgärder som orsakar inkonsekvenser i data. I idealfallet ska alla åtgärder vara idempotenta, så att de kan upprepas utan att orsaka inkonsekvens. Där detta inte är fallet ska återförsöket köras på en nivå eller med en omfattning som tillåter att alla relaterade ändringar kan ångras om en åtgärd misslyckas, till exempel från en transaktionsomfattning. Mer information finns i Cloud Service Fundamentals Data Access Layer – Transient Fault Handling (Dataåtkomslager i Cloud Service Fundamentals – hantering av tillfälliga fel).
- En fast intervallstrategi rekommenderas inte för användning med Azure SQL Database, utom för interaktiva scenarier där det bara finns några få återförsök med mycket korta intervall. Överväg istället att använda en exponentiell backoff-strategi för majoriteten av scenarierna.
- Välj ett lämpligt värde för anslutningen och kommandotimeouter när du definierar anslutningar. För kort timeout kan resultera i för tidiga fel i anslutningar när databasen är upptagen. För lång timeout kan förhindra att omprövningslogiken fungerar som den ska genom att vänta för länge innan en felaktig anslutning identifieras. Värdet för timeouten är en komponent i svarstiden slutpunkt till slutpunkt. Den läggs till effektivt till återförsöksfördröjningen sm anges i återförsöksprincipen för varje återförsök.
- Stäng anslutningen efter ett visst antal återförsök, även när du använder en omprövningslogik för exponentiell backoff och försöker med åtgärden igen på en ny anslutning. Om du försöker med samma åtgärd flera gånger på samma anslutning kan det vara en faktor som bidrar till anslutningsproblem. Ett exempel på den här metoden finns i Cloud Service Fundamentals Data Access Layer – Transient Fault Handling (Dataåtkomslager i Cloud Service Fundamentals – hantering av tillfälliga fel).
- När anslutningspooler används (standard) finns det en risk att samma anslutning väljs i poolen, även efter att en anslutning har stängts och öppnats på nytt. Om så är fallet är en metod att lösa detta att anropa ClearPool-metoden i SqlConnection-klassen för att markera anslutningen som ej återanvändbar. Men du bör bara göra detta efter att flera anslutningsförsök har misslyckats och bara när du träffar på den specifika klassen av tillfälliga fel som SQL-timeouter (felkod -2) relaterade till felaktiga anslutningar.
- Om dataåtkomstkoden använder transaktioner som initierats som TransactionScope-instanser bör omprövningslogiken öppna anslutningen igen och initiera en ny transaktionsomfattning. Av den anledningen ska det återförsökbara kodblocket inbegripa hela omfattningen för transaktionen.
Överväg att börja med följande inställningar för återförsöksåtgärderna. De här inställningarna är generella och du bör övervaka åtgärderna och finjustera värdena så att de passar ditt eget scenario.
| Kontext | Exempelmål E2E maximal svarstid |
Återförsöksstrategi | Inställningar | Värden | Så här fungerar det |
|---|---|---|---|---|---|
| Interaktiv, gränssnitt eller förgrund |
2 sek. | FixedInterval | Antal återförsök Återförsöksintervall Första snabba återförsöket |
3 500 ms true |
Försök 1 – 0 sek. fördröjning Försök 2 – 500 ms fördröjning Försök 3 – 500 ms fördröjning |
| Bakgrund eller batch |
30 sek. | ExponentialBackoff | Antal återförsök Min. backoff Max. backoff Deltabackoff Första snabba återförsöket |
5 0 sek. 60 sek. 2 sek. falskt |
Försök 1 – 0 sek. fördröjning Försök 2 – ~2 sek. fördröjning Försök 3 – ~6 sek. fördröjning Försök 4 – ~14 sek. fördröjning Försök 5 – ~30 sek. fördröjning |
Anteckning
Målen för svarstid slutpunkt till slutpunkt förutsätter standardtimeout för anslutningar till tjänsten. Om du anger längre anslutningstimeouter utökas svarstiden slutpunkt till slutpunkt med denna extra tid för varje återförsök.
Exempel
Det här avsnittet visar hur du kan använda Polly för åtkomst till Azure SQL Database med hjälp av en uppsättning återförsöksprinciper som konfigureras i Policy-klassen.
Följande kod visar en tilläggsmetod i SqlCommand-klassen som anropar ExecuteAsync med exponentiell backoff.
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);
}
Den här asynkrona tilläggsmetoden kan användas på följande sätt.
var sqlCommand = sqlConnection.CreateCommand();
sqlCommand.CommandText = "[some query]";
using (var reader = await sqlCommand.ExecuteReaderWithRetryAsync())
{
// Do something with the values
}
Mer information
- Cloud Service Fundamentals Data Access Layer – Transient Fault Handling (Dataåtkomslager i Cloud Service Fundamentals – hantering av tillfälliga fel)
Allmän vägledning om hur du får ut mesta SQL Database finns i Azure SQL Database för prestanda och elasticitet.
SQL Database med Entity Framework 6
SQL Database är en värdbaserad SQL-databas som finns i flera olika storlekar och som både standardtjänst (delad) och premiumtjänst (inte delad). Entity Framework är en objektrelationell mappningskomponent som gör det möjligt för .NET-utvecklare att arbeta med relationsdata som använder domänspecifika objekt. Den eliminerar behovet av det mesta av den dataåtkomstkod som utvecklare normalt måste skriva.
Återförsöksmekanism
Stöd för återförsök tillhandahålls vid åtkomst SQL Database med Entity Framework 6.0 och senare via en mekanism som kallas anslutningsåter återhämtning/omprövningslogik. Återförsöksmekanismens huvudfunktioner är:
- Den primära abstraktionen är IDbExecutionStrategy-gränssnittet. Gränssnittet gör följande:
- Definierar synkrona och asynkrona körningsmetoder.
- Definierar klasser som kan användas direkt eller kan konfigureras för en databaskontext som en standardstrategi, mappad till ett providernamn eller mappad till ett providernamn och servernamn. När återförsök konfigureras för en kontext sker de på nivån för enskilda databasåtgärder, som det kan finnas flera av för en given kontextåtgärd.
- Definierar när och hur återförsök ska göras för en misslyckad anslutning.
- Den innehåller flera inbyggda implementeringar av IDbExecutionStrategy-gränssnittet:
- Standard: inga återförsök.
- Standard för SQL Database (automatisk): inga återförsök, men inspekterar undantag och omsluter dem med förslag om att använda SQL Database strategi.
- Standard för SQL Database: exponentiell (ärvd från basklass) plus SQL Database identifieringslogik.
- Den implementerar en exponentiell backoff-strategi som inkluderar slumpmässighet.
- De inbyggda återförsöksklasserna är tillståndsfulla och inte trådsäkra. Men de kan återanvändas när den aktuella åtgärden har slutförts.
- Om det angivna antalet återförsök överskrids omsluts resultatet i ett nytt undantag. Den bubblar inte upp det aktuella undantaget.
Principkonfiguration
Funktioner för återförsök ges när SQL Database med Entity Framework 6.0 och senare används. Återförsöksprinciper konfigureras programmässigt. Konfigurationen kan inte ändras på per åtgärd-grund.
När du konfigurerar en strategi för kontexten som standard anger du en funktion som skapar en ny strategi på begäran. Följande kod visar hur du kan skapa en konfigurationsklass för återförsök som utökar DbConfiguration-basklassen.
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)));
}
}
Du kan sedan ange detta som standardstrategin för återförsök för alla åtgärder som använder SetConfiguration-metoden för DbConfiguration-instansen när programmet startas. Som standard identifierar EF konfigurationsklassen automatiskt och använder den.
DbConfiguration.SetConfiguration(new BloggingContextConfiguration());
Du kan ange konfigurationsklassen för återförsök för en kontext genom att kommentera kontextklassen med ett DbConfigurationType-attribut. Men om du bara har en konfigurationsklass använder EF den utan att behöva kommentera kontexten.
[DbConfigurationType(typeof(BloggingContextConfiguration))]
public class BloggingContext : DbContext
Om du behöver använda olika återförsöksstrategier för specifika åtgärder, eller inaktivera återförsök för specifika åtgärder, kan du skapa en konfigurationsklass som gör att du kan inaktivera eller byta strategi genom att ange en flagga i CallContext. Konfigurationsklassen kan använda denna flagga till att byta strategi eller inaktivera strategin du anger och använda en standardstrategi. Mer information finns i Suspend Execution Strategy (EF6 onwards) (Pausa körningsstrategi (EF6 och framåt).
En annan metod för användning av specifika återförsöksstrategier för enskilda åtgärder är att skapa en instans av den strategiklass som krävs och ange önskade inställningar genom parametrar. Du kan anropa dess ExecuteAsync-metod.
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()
);
Det enklaste sättet att använda en DbConfiguration-klass är att hitta den i samma sammansättning som DbContext-klassen. Men detta är inte lämpligt när samma kontext krävs i olika scenarier, till exempel olika interaktiva och bakgrundsbaserade återförsöksstrategier. Om olika kontexter körs i separata AppDomains kan du använda det inbyggda stödet för att ange konfigurationsklasser i konfigurationsfilen eller ange den uttryckligen med hjälp av kod. Om de olika kontexterna måste köras i samma AppDomain krävs det en anpassad lösning.
Mer information finns i Kodbaserad konfiguration (EF6 och framåt).
Följande tabell visar standardinställningarna för den inbyggda återförsöksprincipen vid användning av EF6.
| Inställning | Standardvärde | Innebörd |
|---|---|---|
| Policy | Exponentiellt | Exponentiell backoff. |
| MaxRetryCount | 5 | Max. antal återförsök. |
| MaxDelay | 30 sekunder | Max. fördröjning mellan återförsök. Värdet påverkar inte hur serien med fördröjningar beräknas. Det definierar bara en övre gräns. |
| DefaultCoefficient | 1 sekund | Koefficienten för beräkningen av exponentiell backoff. Värdet kan inte ändras. |
| DefaultRandomFactor | 1.1 | Multiplikatorn som används för att lägga till en slumpmässig fördröjning för varje post. Värdet kan inte ändras. |
| DefaultExponentialBase | 2 | Multiplikatorn som används för att beräkna nästa fördröjning. Värdet kan inte ändras. |
Vägledning för återförsöksanvändning
Tänk på följande när du använder SQL Database med EF6:
Välj lämplig tjänst (delad eller premium). En delad instans kan drabbas av längre anslutningsfördröjningar än normalt och nätverksbegränsningar på grund av andra klientorganisationers användning av den delade servern. Om förutsägbara prestanda och tillförlitliga åtgärder med låg latens krävs kan du överväga att använda premiumalternativet.
En fast intervallstrategi rekommenderas inte för användning med Azure SQL Database. Använd istället en exponentiell backoff-strategi eftersom tjänsten kan vara överbelastad och längre fördröjningar tillåter mer tid för att den ska återställas.
Välj ett lämpligt värde för anslutningen och kommandotimeouter när du definierar anslutningar. Basera timeouten på din affärslogik och genom testning. Du kanske måste ändra värdet med tiden då datamängden eller affärsprocesserna ändras. För kort timeout kan resultera i för tidiga fel i anslutningar när databasen är upptagen. För lång timeout kan förhindra att omprövningslogiken fungerar som den ska genom att vänta för länge innan en felaktig anslutning identifieras. Värdet av timeouten är en komponent i svarstiden slutpunkt till slutpunkt, men du kan inte på ett enkelt sätt fastställa hur många kommandon som körs när du sparar kontexten. Du kan ändra standardtimeouten genom att ange egenskapen CommandTimeout i DbContext-instansen.
Entity Framework stödjer återförsökskonfigurationer som definieras i konfigurationsfiler. Men för maximal flexibilitet i Azure bör du skapa konfigurationen programmässigt i programmet. De specifika parametrarna för återförsöksprinciperna, till exempel antalet återförsök och återförsöksintervall, kan lagras i tjänstekonfigurationsfilen och användas vid körning för att skapa rätt principer. Det gör att inställningarna kan ändras utan att programmet behöver startas om.
Överväg att börja med följande inställningar för återförsöksåtgärderna. Du kan inte ange fördröjningen mellan återförsök (den är fast och genereras som en exponentiell sekvens). Du kan bara ange de maxvärden som visas här, om du inte skapar en anpassad återförsöksstrategi. De här inställningarna är generella och du bör övervaka åtgärderna och finjustera värdena så att de passar ditt eget scenario.
| Kontext | Exempelmål E2E maximal svarstid |
Återförsöksprincip | Inställningar | Värden | Så här fungerar det |
|---|---|---|---|---|---|
| Interaktiv, gränssnitt eller förgrund |
2 sekunder | Exponentiellt | MaxRetryCount MaxDelay |
3 750 ms |
Försök 1 – 0 sek. fördröjning Försök 2 – 750 ms fördröjning Försök 3 – 750 ms fördröjning |
| Bakgrund eller batch |
30 sekunder | Exponentiellt | MaxRetryCount MaxDelay |
5 12 sekunder |
Försök 1 – 0 sek. fördröjning Försök 2 – ~1 sek. fördröjning Försök 3 – ~3 sek. fördröjning Försök 4 – ~7 sek. fördröjning Försök 5 – 12 sek. fördröjning |
Anteckning
Målen för svarstid slutpunkt till slutpunkt förutsätter standardtimeout för anslutningar till tjänsten. Om du anger längre anslutningstimeouter utökas svarstiden slutpunkt till slutpunkt med denna extra tid för varje återförsök.
Exempel
I följande kodexempel definieras en enkel dataåtkomstlösning som använder Entity Framework. Den anger en specifik återförsöksstrategi genom att definiera en instans av klassen BlogConfiguration som utökar 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();
}
}
}
}
Fler exempel på hur du Entity Framework återförsöksmekanismen finns i Anslutningsåter återhämtning/omprövningslogik.
Mer information
SQL Database med Entity Framework Core
Entity Framework Core är en objektrelationell mappningskomponent som gör det möjligt för .NET Core-utvecklare att arbeta med data som använder domänspecifika objekt. Den eliminerar behovet av det mesta av den dataåtkomstkod som utvecklare normalt måste skriva. Den här versionen av Entity Framework har skrivits från grunden och ärver inte automatiskt alla funktioner från EF6.x.
Återförsöksmekanism
Stöd för återförsök tillhandahålls vid åtkomst till SQL Database med Entity Framework Core via en mekanism som kallas anslutningsåter återhämtning. Anslutningsåterhämtning introducerades i EF Core 1.1.0.
Den primära abstraktionen är IExecutionStrategy-gränssnittet. Körningsstrategin för SQL Server, inklusive SQL Azure, är medveten om undantagstyperna som kan omprövas och har rimliga standardvärden för max. antal återförsök, fördröjning mellan återförsök och så vidare.
Exempel
Följande kod möjliggör automatiska återförsök när DbContext-objektet konfigureras, vilket representerar en session med databasen.
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer(
@"Server=(localdb)\mssqllocaldb;Database=EFMiscellaneous.ConnectionResiliency;Trusted_Connection=True;",
options => options.EnableRetryOnFailure());
}
Följande kod visar hur du kör en transaktion med automatiska återförsök, genom att använda en körningsstrategi. Transaktionen definieras i en delegate. Om det inträffar ett tillfälligt fel anropar körningsstrategin delegate igen.
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 tjänster omfattar bloblagring, filer och lagringsköer.
Blobar, köer och filer
Klassen ClientOptions är bastypen för alla klientalternativtyper och visar olika vanliga klientalternativ som Diagnostik, Försök igen, Transport. Om du vill ange klientkonfigurationsalternativ för att ansluta till Azure Queue, Blob och File Storage du använda motsvarande härledd typ. I nästa exempel använder du klassen QueueClientOptions (härledd från ClientOptions) för att konfigurera en klient att ansluta till Azure Queue Service. Egenskapen Försök igen är den uppsättning alternativ som kan anges för att påverka hur återförsök görs och hur ett fel kan försökas igen.
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);
Tabellstöd
Anteckning
WindowsAzure. Storage Nuget-paketet har gjorts inaktuellt. Stöd för Azure-tabeller finns i Microsoft.Azure.Cosmos.Table Nuget Package
Återförsöksmekanism
Nya försök sker på enskild REST-åtgärdsnivå och är en integrerad del av implementeringen av klient-API. Klientlagrings-SDK använder klassar som implementerar IExtendedRetryPolicy-gränssnittet.
De inbyggda klasserna ger stöd för linjär (konstant fördröjning) och exponentiell med slumpmässiga återförsöksintervall. Det finns inte heller någon återförsöksprincip när en annan process hanterar återförsök på en högre nivå. Men du kan implementera dina egna återförsöksklasser om du har specifika krav som inte ges av de inbyggda klasserna.
Alternativa återförsök växlar mellan primär och sekunder lagringstjänsteplats om du använder geo-redundant lagring med läsåtkomst (RA-GRS) och resultatet av begäran är ett fel där det går att göra ett återförsök. Mer information finns i Redundansalternativ för Azure Storage.
Principkonfiguration
Återförsöksprinciper konfigureras programmässigt. En vanlig metod är att skapa och fylla i en TableRequestOptions-, BlobRequestOptions-, FileRequestOptions- eller QueueRequestOptions-instans.
TableRequestOptions interactiveRequestOption = new TableRequestOptions()
{
RetryPolicy = new LinearRetry(TimeSpan.FromMilliseconds(500), 3),
// For Read-access geo-redundant storage, use PrimaryThenSecondary.
// Otherwise set this to PrimaryOnly.
LocationMode = LocationMode.PrimaryThenSecondary,
// Maximum execution time based on the business use case.
MaximumExecutionTime = TimeSpan.FromSeconds(2)
};
Instansen för begäranalternativ kan anges på klienten och alla åtgärder med klienten använder de angivna begäran alternativen.
client.DefaultRequestOptions = interactiveRequestOption;
var stats = await client.GetServiceStatsAsync();
Du kan åsidosätta klientbegäranalternativen genom att överföra en ifylld instans med klassen för begäranalternativ som en parameter till åtgärdsmetoder.
var stats = await client.GetServiceStatsAsync(interactiveRequestOption, operationContext: null);
Du kan använda en OperationContext-instans till att ange koden som körs när ett återförsök inträffar och när en åtgärd har slutförts. Denna kod kan samla in information om åtgärden för användning i loggar och telemetri.
// Set up notifications for an operation
var context = new OperationContext();
context.ClientRequestID = "some request id";
context.Retrying += (sender, args) =>
{
// Collect retry information
};
context.RequestCompleted += (sender, args) =>
{
// Collect operation completion information
};
var stats = await client.GetServiceStatsAsync(null, context);
Utöver att ange om det är lämpligt att försöka igen vid ett fel returnerar de utökade återförsksprinciperna ett RetryContext-objekt som indikerar antalet återförsök, resultatet av den senaste begäran, om nästa återförsök sker på den primära eller sekundära platsen (se tabellen nedan för information). Egenskaperna för RetryContext-objektet kan användas för att fastställa om och när det ska göras ett nytt försök. Mer information finns i IExtendedRetryPolicy.Evaluate-metoden.
I följande tabell visas standardinställningarna för de inbyggda återförsöksprinciperna.
Alternativ för begäran:
| Inställning | Standardvärdet | Innebörd |
|---|---|---|
| MaximumExecutionTime | Ingen | Maximal körningstid för begäran, inklusive alla potentiella återförsök. Om den inte anges är den tid som en begäran tillåts ta obegränsad. Med andra ord kan begäran sluta svara. |
| ServerTimeout | Ingen | Servertimeoutintervall för begäran (värdet avrundas till sekunder). Om det inte anges används standardvärdet för alla begäranden till servern. Normalt är det bästa alternativet att utelämna den här inställningen så att serverstandardvärdet används. |
| LocationMode | Ingen | Om lagringskontot används med RA-GRS-replikeringsalternativet kan du används platsläget för att ange vilken plats som ska ta emot begäran. Om till exempel PrimaryThenSecondary anges skickas begäranden alltid till den primära platsen först. Om en begäran misslyckas skickas den till den sekundära platsen. |
| RetryPolicy | ExponentialPolicy | Se nedan för information om varje alternativ. |
Exponentiell princip:
| Inställning | Standardvärdet | Innebörd |
|---|---|---|
| maxAttempt | 3 | Antal återförsök. |
| deltaBackoff | 4 sekunder | Backoffintervall mellan återförsök. Multiplar för den här tiden, inklusive ett slumpmässigt element, används för efterföljande återförsök. |
| MinBackoff | 3 sekunder | Läggs till i alla återförsöksinterval som beräknas från deltaBackoff. Värdet kan inte ändras. |
| MaxBackoff | 120 sekunder | MaxBackoff används om det beräknade återförsöksintervallet är större än MaxBackoff. Värdet kan inte ändras. |
Linjär princip:
| Inställning | Standardvärdet | Innebörd |
|---|---|---|
| maxAttempt | 3 | Antal återförsök. |
| deltaBackoff | 30 sekunder | Backoffintervall mellan återförsök. |
Vägledning för återförsöksanvändning
Tänk på följande rekommendationer vid användning av Azure Storage-tjänster med lagringsklient-API:
Använd de inbyggda återförsöksprinciperna från Microsoft.Azure. Storage. RetryPolicies-namnområdet där de är lämpliga för dina behov. I de flesta fall är dessa principer tillräckliga.
Använd ExponentialRetry-principen i batchåtgärder, bakgrundsuppgifter eller icke-interaktiva scenarier. I dessa scenarier kan du normalt tillåta mer tid för tjänsten att återställas – med en ökad chans att åtgärden till slut lyckas.
Överväg att ange egenskapen MaximumExecutionTime för parametern RequestOptions för att begränsa den totala körningstiden men ta hänsyn till åtgärdens typ och storlek när du väljer ett timeoutvärde.
Om du behöver implementera ett anpassat återförsök ska du undvika att skapa omslutningar kring lagringsklientklasserna. Använd istället funktionerna för att utöka de befintliga principerna genom IExtendedRetryPolicy-gränssnittet.
Om du använder RA-GRS kan du använda LocationMode till att ange att återförsöken kommer åt den sekundära skrivskyddade kopian av lagret om den primära åtkomsten misslyckas. Men när du använder det här alternativet måste du se till att programmet kan fungerar med data som kan vara inaktuella om replikeringen från det primära lagret inte har slutförts än.
Överväg att börja med följande inställningar för återförsöksåtgärderna. De här inställningarna är generella och du bör övervaka åtgärderna och finjustera värdena så att de passar ditt eget scenario.
| Kontext | Exempelmål E2E maximal svarstid |
Återförsöksprincip | Inställningar | Värden | Så här fungerar det |
|---|---|---|---|---|---|
| Interaktiv, gränssnitt eller förgrund |
2 sekunder | Linjär | maxAttempt deltaBackoff |
3 500 ms |
Försök 1 – 500 ms fördröjning Försök 2 – 500 ms fördröjning Försök 3 – 500 ms fördröjning |
| Bakgrund eller batch |
30 sekunder | Exponentiellt | maxAttempt deltaBackoff |
5 4 sekunder |
Försök 1 – ~3 sek. fördröjning Försök 2 – ~7 sek. fördröjning Försök 3 – ~15 sek. fördröjning |
Telemetri
Återförsök loggas i ett TraceSource. Du måste konfigurera en TraceListener för att registrera händelserna och skriva dem till en lämplig mållogg. Du kan använda TextWriterTraceListener eller XmlWriterTraceListener för att skriva data till en loggfil, EventLogTraceListener för att skriva till händelseloggen för Windows eller EventProviderTraceListener för att skriva spårningsdata till ETW-undersystemet. Du kan också konfigurera automatisk inströmning av bufferten och de utförliga händelser som ska loggas (till exempel Fel, Varning, Information och Utförlig). Mer information finns i artikeln om klientloggning med .NET Storage Client Library.
Åtgärder kan ta emot en OperationContext-instans, som visar en Retrying-händelse som kan användas till att koppla anpassad telemetrilogik. Mer information finns i OperationContext.Retrying Event.
Exempel
Följande kodexempel visar hur du skapar två TableRequestOptions-instanser med olika återförsöksinställningar, en för interaktiva begäranden och en för bakgrundsbegäranden. Exemplet anger sedan dessa två återförsöksprinciper så att de gäller för alla begäranden, och anger även den interaktiva strategin för en specifik begäran så att den åsidosätter standardinställningen som tillämpas på klienten.
using System;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos.Table;
namespace RetryCodeSamples
{
class AzureStorageCodeSamples
{
private const string connectionString = "UseDevelopmentStorage=true";
public async static Task Samples()
{
var storageAccount = CloudStorageAccount.Parse(connectionString);
TableRequestOptions interactiveRequestOption = new TableRequestOptions()
{
RetryPolicy = new LinearRetry(TimeSpan.FromMilliseconds(500), 3),
// For Read-access geo-redundant storage, use PrimaryThenSecondary.
// Otherwise set this to PrimaryOnly.
LocationMode = LocationMode.PrimaryThenSecondary,
// Maximum execution time based on the business use case.
MaximumExecutionTime = TimeSpan.FromSeconds(2)
};
TableRequestOptions backgroundRequestOption = new TableRequestOptions()
{
// Client has a default exponential retry policy with 4 sec delay and 3 retry attempts
// Retry delays will be approximately 3 sec, 7 sec, and 15 sec
MaximumExecutionTime = TimeSpan.FromSeconds(30),
// PrimaryThenSecondary in case of Read-access geo-redundant storage, else set this to PrimaryOnly
LocationMode = LocationMode.PrimaryThenSecondary
};
var client = storageAccount.CreateCloudTableClient();
// Client has a default exponential retry policy with 4 sec delay and 3 retry attempts
// Retry delays will be approximately 3 sec, 7 sec, and 15 sec
// ServerTimeout and MaximumExecutionTime are not set
{
// Set properties for the client (used on all requests unless overridden)
// Different exponential policy parameters for background scenarios
client.DefaultRequestOptions = backgroundRequestOption;
// Linear policy for interactive scenarios
client.DefaultRequestOptions = interactiveRequestOption;
}
{
// set properties for a specific request
var stats = await client.GetServiceStatsAsync(interactiveRequestOption, operationContext: null);
}
{
// Set up notifications for an operation
var context = new OperationContext();
context.ClientRequestID = "some request id";
context.Retrying += (sender, args) =>
{
// Collect retry information
};
context.RequestCompleted += (sender, args) =>
{
// Collect operation completion information
};
var stats = await client.GetServiceStatsAsync(null, context);
}
}
}
}
Mer information
Azure Storage rekommendationer för återförsöksprincip i klientbiblioteket
Storage Client Library 2.0 – Implementera återförsöksprinciper
Allmänna riktlinjer för REST och återförsök
Tänk på följande när du använder Azure eller tjänster från tredje part:
Hantera återförsök systematiskt, kanske som återanvändbar kod, så att du kan tillämpa konsekventa metoder för alla klienter och lösningar.
Överväg att använda ett ramverk för återförsök, till exempel Polly, för att hantera återförsök om måltjänsten eller klienten inte har någon inbyggd återförsöksmekanism. Det hjälper dig att implementera en konsekvent återförsöksbeteende och det kan ge en lämplig standardstrategi för återförsök för måltjänsten. Du kan dock behöva skapa anpassad återförsökskod för tjänster som har icke-standardbeteende, som inte förlitar sig på undantag för att indikera tillfälliga fel eller om du vill använda ett Retry-Response-svar för att hantera återförsöksbeteendet.
Den tillfälliga identifieringslogiken är beroende av det faktiska klient-API:et som du kan anropa REST-anropen med. Vissa klienter, till exempel den nyare HttpClient-klassen utlöser inte undantag för slutförda begäranden med en HTTP-statuskod för misslyckad åtgärd.
HTTP-statuskoden som returneras från tjänsten kan hjälpa till att ange om felet är tillfälligt. Du kan behöva undersöka undantagen som genereras av en klient eller återförsöksramverket för att komma åt statuskoden eller för att fastställa motsvarande undantagstyp. Följande HTTP-koder anger vanligtivs att ett nytt försök är lämpligt:
- 408 Timeout för begäran
- 429 För många förfrågningar
- 500 internt serverfel
- 502 Felaktig gateway
- 503 Tjänsten är inte tillgänglig
- 504 Gateway-timeout
Om du baserar omprövningslogiken på undantag anger följande vanligtvis ett tillfälligt fel när det inte har gått att upprätta en anslutning:
- WebExceptionStatus.ConnectionClosed
- WebExceptionStatus.ConnectFailure
- WebExceptionStatus.Timeout
- WebExceptionStatus.RequestCanceled
När det gäller statusen för otillgänglig tjänst kan tjänsten ange lämplig fördröjning innan nytt försök görs i svarshuvudet Retry-After eller ett annat anpassat huvud. Tjänster kan även skicka ytterligare information som anpassade huvuden eller inbäddad i svarets innehåll.
Försök inte igen för statuskoder som representerar klientfel (fel i 4xx-intervallet) förutom 408 Timeout för begäran och 429 För många begäranden.
Testa dina återförsöksstrategier och -mekanismer noga i olika förhållanden, till exempel olika nätverkstillstånd och systembelastningar.
Återförsöksstrategier
Följande är vanliga typer av intervall för återförsstrategier:
Exponentiell . En återförsöksprincip som utför ett angivet antal återförsök, med hjälp av en slumpmässig exponentiell back off-metod för att fastställa intervallet mellan återförsök. Till exempel:
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);Inkrementell . En strategi för återförsök med ett angivet antal återförsök och ett inkrementellt tidsintervall mellan återförsök. Till exempel:
retryInterval = TimeSpan.FromMilliseconds(this.initialInterval.TotalMilliseconds + (this.increment.TotalMilliseconds * currentRetryCount));LinearRetry. En återförsöksprincip som utför ett angivet antal återförsök, med ett angivet fast tidsintervall mellan återförsök. Till exempel:
retryInterval = this.deltaBackoff;
Hantering av tillfälliga fel med Polly
Polly är ett bibliotek för att programmatiskt hantera strategier för återförsök och kretsbrytare. Polly-projektet är en medlem i .NET Foundation. För tjänster där klienten inte stöder återförsök internt är Polly ett bra alternativ där du kan undvika att skriva anpassad återförsökskod, vilket kan vara svårt att implementera på rätt sätt. Med Polly kan du också spåra fel när de inträffar, så att du kan logga återförsök.