Pokyny k opakování pro služby Azure
Mechanismus opakování obsahuje většina služeb Azure a klientských sad SDK. Tyto mechanismy se ale liší, protože každá služba má jiné vlastnosti a požadavky, takže každý mechanismus opakování je vyladěný pro konkrétní službu. Tento průvodce shrnuje funkce mechanismu opakování pro většinu služeb Azure a obsahuje informace, které vám pomůžou použít, přizpůsobit nebo rozšířit mechanismus opakování pro určitou službu.
Obecné pokyny ke zpracování přechodných chyb a k opakování připojení a operací u služeb a prostředků najdete v pokynech pro opakování.
Funkce opakování pro služby Azure popisované v těchto pokynech shrnuje následující tabulka.
| Služba | Funkce opakování | Konfigurace zásad | Scope | Telemetrické funkce |
|---|---|---|---|---|
| Azure Active Directory | Nativní v knihovně MSAL | Vložené do knihovny MSAL | Interní | Žádné |
| Cosmos DB | Nativní ve službě | Nekonfigurovatelné | Globální | TraceSource |
| Data Lake Store | Nativní v klientovi | Nekonfigurovatelné | Jednotlivé operace | Žádné |
| Event Hubs | Nativní v klientovi | Programová | Klient | Žádné |
| IoT Hub | Nativní v klientské sadě SDK | Programová | Klient | Žádné |
| Azure Cache for Redis | Nativní v klientovi | Programová | Klient | TextWriter |
| Hledat | Nativní v klientovi | Programová | Klient | Trasování událostí pro Windows nebo vlastní |
| Service Bus | Nativní v klientovi | Programová | Namespace Manager, Messaging Factory a klient | Trasování událostí pro Windows |
| Service Fabric | Nativní v klientovi | Programová | Klient | Žádné |
| SQL Database s ADO.NET | Polly | Deklarativní a programová | Jednotlivé příkazy nebo bloky kódu | Vlastní |
| SQL Database s Entity Framework | Nativní v klientovi | Programová | Globální na doménu aplikace | Žádné |
| SQL Database s Entity Framework Core | Nativní v klientovi | Programová | Globální na doménu aplikace | Žádné |
| Storage | Nativní v klientovi | Programová | Klient a jednotlivé operace | TraceSource |
Poznámka
U většiny integrovaných mechanismů opakování Azure v současné době neexistuje způsob, jak použít jiné zásady opakování pro různé typy chyb nebo výjimek. Měli byste nakonfigurovat zásadu, která poskytuje optimální průměrný výkon a dostupnost. Jedna z možností, jak zásady vyladit, je určit typ přechodných chyb, ke kterým dochází.
Azure Active Directory
Azure Active Directory (Azure AD) je komplexní cloudové řešení pro správu identit a přístupu, které představuje kombinaci základních adresářových služeb, rozšířené správy identit, zabezpečení a správy přístupu k aplikacím. Azure AD také nabízí vývojářům platformu pro správu identit, která na základě centralizovaných zásad a pravidel obstarává řízení přístupu k jejich aplikacím.
Poznámka
Pokyny k opakování koncových bodů identity spravované služby najdete v tématu Použití identity spravované služby (MSI) virtuálního počítače Azure k získání tokenu.
Mechanismus opakování
K dispozici je integrovaný mechanismus opakování pro Azure Active Directory v knihovně MICROSOFT Authentication Library (MSAL). Pokud se chcete vyhnout neočekávaným uzamčením, doporučujeme, aby knihovny třetích stran a kód aplikace nezkoušely neúspěšná připojení opakovat, ale umožnily knihovně MSAL zpracovávat opakování.
Pokyny k použití opakování
Zvažte následující pokyny pro používání služby Azure Active Directory:
- Pokud je to možné, pro opakování použijte knihovnu MSAL a integrovanou podporu.
- Pokud používáte rozhraní REST API pro Azure Active Directory, zkuste operaci zopakovat, pokud je kód výsledku 429 (příliš mnoho požadavků) nebo chyba v rozsahu 5xx. U jiných chyb operaci neopakujte.
- V případě chyb 429 zkuste akci zopakovat pouze po čase uvedeném v hlavičce Retry-After.
- V případě chyb 5xx použijte exponenciální opakování s prvním opakováním alespoň 5 sekund po odpovědi.
- Při jiných chybách než 429 a 5xx pokus opakujte.
Další informace
Cosmos DB
Cosmos DB je plně spravovaná databáze s více modely, která podporuje data JSON bez schématu. Nabízí konfigurovatelný a spolehlivý výkon, nativní zpracování transakcí JavaScript a je vytvořená pro cloud s pružným škálováním.
Mechanismus opakování
Třída CosmosClient automaticky opakuje neúspěšné pokusy. Pokud chcete nastavit počet opakovaných pokusů a maximální dobu čekání, nakonfigurujte CosmosClientOptions. Výjimky vyvolané klientem jsou nad rámec zásad opakování nebo to nejsou přechodné chyby.
Pokud Cosmos DB omezí klienta, vrátí se chyba HTTP 429. Kontroluje stavový kód ve CosmosException třídě.
Konfigurace zásad
Následující tabulka ukazuje výchozí nastavení pro třídu CosmosClientOptions.
| Nastavení | Výchozí hodnota | Popis |
|---|---|---|
| MaxRetryAttemptsOnRateLimitedRequests | 9 | Maximální počet opakovaných pokusů v případě, že žádost selže, protože databáze Cosmos DB použila na klienta omezení rychlosti. |
| MaxRetryWaitTimeOnRateLimitedRequests | 30 | maximální doba opakování v sekundách pro službu Azure Cosmos DB. |
Příklad
CosmosClient cosmosClient = new CosmosClient("connection-string", new CosmosClientOptions()
{
MaxRetryAttemptsOnRateLimitedRequests = 5,
MaxRetryWaitTimeOnRateLimitedRequests = TimeSpan.FromSeconds(15)
});
Telemetrie
Opakované pokusy se protokolují jako nestrukturované zprávy trasování prostřednictvím .NET TraceSource. Je nutné nakonfigurovat TraceListener k zachycení událostí a jejich zápisu do vhodného cílového protokolu.
Pokud například přidáte do souboru App.config následující kód, budou se trasování generovat v textovém souboru, který je ve stejném umístění jako spustitelný soubor:
<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 je služba pro ingestování telemetrie s škálovatelným škálováním, která shromažďuje, transformuje a ukládá miliony událostí.
Mechanismus opakování
Chování při opakování je v klientské knihovně Azure Event Hubs řízené vlastností RetryPolicy ve třídě EventHubClient. Když služba Azure Event Hubs vrátí přechodnou výjimku EventHubsException nebo výjimku OperationCanceledException, výchozí zásady opakují pokus exponenciální regresí. Výchozí zásada opakování pro Event Hubs je opakování až 9 časů s exponenciálním časem zálohování až 30 sekund.
Příklad
EventHubClient client = EventHubClient.CreateFromConnectionString("[event_hub_connection_string]");
client.RetryPolicy = RetryPolicy.Default;
Další informace
Klientská knihovna .NET Standard pro Azure Event Hubs
IoT Hub
Azure IoT Hub je služba pro připojení, monitorování a správu zařízení pro vývoj aplikací Internet věcí (IoT).
Mechanismus opakování
Sada SDK pro zařízení Azure IoT dokáže detekovat chyby v síti, protokolu nebo aplikaci. Na základě typu chyby sada SDK kontroluje, zda je třeba provést opakování. Pokud je chyba obnovitelná, sada SDK začne znovu používat nakonfigurované zásady opakování.
Výchozí zásada opakování je exponenciální, pokud má náhodnou kolísání, ale dá se nakonfigurovat.
Konfigurace zásad
Konfigurace zásad se liší podle jazyka. Další podrobnosti najdete v tématu Konfigurace zásad pro opakování IoT Hub.
Další informace
Azure Cache for Redis
Mezipaměť Azure pro Redis je rychlá služba pro přístup k datům a s nízkou latencí v mezipaměti založená na oblíbené open source mezipaměti Redis. Je zabezpečená, spravovaná Microsoftem a přístupná z libovolné aplikace v Azure.
Pokyny v této části vycházejí z předpokladu, že se pro přístup k mezipaměti používá klient StackExchange.Redis. Seznam dalších vhodných klientů můžete najít na webu Redis. Tito klienti můžou mít jiné mechanismy opakování.
Upozorňujeme, že klient StackExchange.Redis používá multiplexing přes jedno připojení. Doporučuje se vytvořit instanci klienta při spuštění aplikace a používat tuto instanci pro všechny operace s mezipamětí. Z tohoto důvodu se připojení k mezipaměti provede jenom jednou a všechny pokyny v této části se vztahují k zásadám opakování pro toto počáteční připojení — a nikoli ke každé operaci, která přistupuje k mezipaměti.
Mechanismus opakování
Klient StackExchange. Redis používá třídu Správce připojení, která je nakonfigurovaná pomocí sady možností, včetně:
- ConnectRetry. Počet opakovaných pokusů při neúspěšném připojení k mezipaměti.
- ReconnectRetryPolicy. Používaná strategie opakování.
- ConnectTimeout. Maximální doba čekání v milisekundách.
Konfigurace zásad
Zásady opakování se konfigurují programově – nastavením možností pro klienta před připojováním k mezipaměti. Dá se to udělat tak, že se vytvoří instance třídy ConfigurationOptions, naplní se její vlastnosti a předá se metodě Connect.
Předdefinované třídy podporují lineární (konstantní) zpoždění a exponenciální regresi s náhodnými intervaly opakování. Také můžete vytvořit vlastní zásady opakování – implementací rozhraní IReconnectRetryPolicy.
V následujícím příkladu nakonfigurujeme strategii opakování s exponenciální regresí.
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);
Možnosti můžete případně zadat jako řetězec a tento řetězec předat metodě Connect. Vlastnost ReconnectRetryPolicy nelze nastavit tímto způsobem, pouze prostřednictvím kódu.
var options = "localhost,connectRetry=3,connectTimeout=2000";
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);
Možnosti můžete také zadat přímo při připojení k mezipaměti.
var conn = ConnectionMultiplexer.Connect("redis0:6380,redis1:6380,connectRetry=3");
Další informace najdete v dokumentaci StackExchange.Redis v části o konfiguraci Stack Exchange Redis.
Následující tabulka ukazuje výchozí nastavení pro předdefinované zásady opakování.
| Kontext | Nastavení | Výchozí hodnota (v. 1.2.2) |
Význam |
|---|---|---|---|
| ConfigurationOptions | ConnectRetry ConnectTimeout SyncTimeout ReconnectRetryPolicy |
3 Maximálně 5000 ms plus SyncTimeout 1000 LinearRetry 5000 ms |
Počet opakovaných pokusů o připojení během počáteční operace připojení. Časový limit (ms) pro operace připojení. Není to zpoždění mezi opakovanými pokusy. Doba (ms) pro synchronní operace. Opakování po 5000 ms. |
Poznámka
U synchronních operací může SyncTimeout prodlužovat celkovou latenci, když ale nastavíte tuto hodnotu příliš nízkou, může to způsobit nadměrná vypršení časových limitů. Přečtěte si téma řešení potíží s Azure cache pro Redis. Obecně doporučujeme používat místo synchronních operací asynchronní. další informace najdete v tématu Pipelines a multiplexor.
Pokyny k použití opakování
Při používání mezipaměti Azure pro Redis Vezměte v úvahu následující pokyny:
- Klient StackExchange Redis spravuje vlastní opakované pokusy, ale jenom při navazování připojení při počátečním spuštění aplikace. Dá se konfigurovat časový limit připojení, počet opakovaných pokusů a doba mezi opakovanými pokusy o navázání tohoto připojení, ale pro operace s mezipamětí neplatí zásady opakování.
- Místo použití velkého počtu opakovaných pokusů zvažte nouzové přepnutí na přístup k původnímu zdroji dat.
Telemetrie
Můžete použít TextWriter a shromažďovat informace o připojeních (ale ne o jiných operacích).
var writer = new StringWriter();
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);
Níže je uvedený příklad vygenerovaného výstupu.
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...
...
Příklady
Následující příklad kódu konfiguruje konstantní (lineární) zpoždění mezi opakovanými pokusy při inicializaci klienta StackExchange.Redis. Tento příklad ukazuje, jak nastavit konfiguraci pomocí instance ConfigurationOptions.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StackExchange.Redis;
namespace RetryCodeSamples
{
class CacheRedisCodeSamples
{
public async static Task Samples()
{
var writer = new StringWriter();
{
try
{
var retryTimeInMilliseconds = TimeSpan.FromSeconds(4).TotalMilliseconds; // delay between retries
// Using object-based configuration.
var options = new ConfigurationOptions
{
EndPoints = { "localhost" },
ConnectRetry = 3,
ReconnectRetryPolicy = new LinearRetry(retryTimeInMilliseconds)
};
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);
// Store a reference to the multiplexer for use in the application.
}
catch
{
Console.WriteLine(writer.ToString());
throw;
}
}
}
}
}
Následující příklad ukazuje, jak nastavit konfiguraci zadáním možností ve formě řetězce. Časový limit připojení je maximální doba čekání na připojení k mezipaměti, není to zpoždění mezi opakovanými pokusy. Upozorňujeme, že vlastnost ReconnectRetryPolicy se dá nastavit jenom pomocí kódu.
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;
}
}
}
}
}
Další informace najdete na webu projektu v článku o konfiguraci.
Další informace
Azure Search
Služba Azure Search se dá použít k přidání výkonných a důmyslných možností vyhledávání na web nebo do aplikace, k rychlému a snadnému vyladění výsledků hledání a k vytvoření složitých, jemně vyladěných modelů řazení.
Mechanismus opakování
Chování při opakování je v sadě SDK Azure Search řízené metodou SetRetryPolicy ve třídách SearchServiceClient a SearchIndexClient. Když služba Azure Search vrátí odpověď 5xx nebo 408 (Časový limit žádosti), výchozí zásady opakují pokus s exponenciální regresí.
Telemetrie
Trasujte pomocí Trasování událostí pro Windows nebo si zaregistrujte vlastního zprostředkovatele trasování. Další informace najdete v dokumentaci k AutoRestu.
Service Bus
Service Bus je cloudová platforma zasílání zpráv, která umožňuje volně spojenou výměnu zpráv s lepší škálovatelností a odolností součástí aplikací, ať už je hostovaná v cloudu nebo místně.
Mechanismus opakování
Service Bus implementuje opakované pokusy pomocí implementací abstraktní třídy RetryPolicy . obor názvů a některé podrobnosti konfigurace závisí na tom, který Service Bus balíček klientské sady SDK se používá:
| Balíček | Popis | Obor názvů |
|---|---|---|
| Microsoft. Azure. ServiceBus | klientská knihovna Azure Service Bus pro .NET Standard. | Microsoft.ServiceBus |
| WindowsAzure. ServiceBus | tento balíček je starší klientská knihovna Service Bus. vyžaduje .NET Framework 4.5.2. | Microsoft.Azure.ServiceBus |
Obě verze klientské knihovny poskytují následující předdefinované implementace RetryPolicy :
RetryExponential. Implementuje exponenciální omezení rychlosti.
Neopakovat. Neprovádí opakované pokusy. tuto třídu použijte, pokud nepotřebujete opakované pokusy na úrovni rozhraní Service Bus API, například když jiný proces spravuje opakované pokusy jako součást operace batch nebo více kroků.
RetryPolicy.DefaultVlastnost vrací výchozí zásady typu RetryExponential . Tento objekt zásad má následující nastavení:
| Nastavení | Výchozí hodnota | Význam |
|---|---|---|
| MinimalBackoff | 0 | Minimální regresní interval. Přidáno do intervalu opakování vypočítaného z deltaBackoff . |
| MaximumBackoff | 30 sekund | Maximální regresní interval. |
| DeltaBackoff | 3 sekundy | Regresní interval mezi opakovanými pokusy. Pro následující opakované pokusy se používají násobky tohoto časového rozsahu. |
| MaxRetryCount | 5 | Maximální počet opakování. (Výchozí hodnota je 10 v WindowsAzure.ServiceBus balíčku.) |
Kromě toho je ve starším balíčku definovaná Tato vlastnost WindowsAzure.ServiceBus :
| Nastavení | Výchozí hodnota | Význam |
|---|---|---|
| TerminationTimeBuffer | 5 sekund | Pokusy o opakování budou ukončeny, pokud je zbývající čas menší než tato hodnota. |
Service Bus akce mohou vracet rozsah výjimek, které jsou uvedeny v části Service Bus výjimky zasílání zpráv. výjimky vracené z Service Bus zpřístupňují vlastnost- přechodný , která indikuje, jestli se má klient pokusit zopakovat operaci. Předdefinované zásady RetryExponential před opakováním kontrolují tuto vlastnost.
Pokud se poslední zjištěná výjimka výjimka serverbusyexception, zásada RetryExponential přidá 10 sekund do vypočítaného intervalu opakování. Tato hodnota se nedá změnit.
Vlastní implementace mohou používat kombinaci typu výjimky a vlastnost- přechodný k zajištění přesnější kontroly nad akcemi opakování. Můžete třeba zjišťovat výjimku QuotaExceededException a podniknout akci k vyprázdnění fronty, než se znovu pokusíte poslat do fronty zprávu.
následující kód nastaví zásady opakování u klienta Service Bus pomocí Microsoft.Azure.ServiceBus knihovny:
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);
Zásady opakování nejdou nastavit na úrovni jednotlivých operací. Platí pro všechny operace klienta.
Pokyny k použití opakování
Zvažte následující pokyny pro používání služby Service Bus:
- Při použití předdefinované implementace RetryExponential neimplementujte nouzový provoz, protože zásady reagují na výjimky ServerBusy a automaticky přepnou do patřičného režimu opakování.
- Service Bus podporuje funkci nazvanou spárované obory názvů, která implementuje automatické převzetí služeb při selhání do fronty zálohování v samostatném oboru názvů, pokud se fronta v primárním oboru názvů nezdařila. Až se primární fronta zotaví, můžou se zprávy ze sekundární fronty poslat zpátky do primární fronty. Tato funkce pomáhá řešit přechodná selhání. Další informace najdete v článku o asynchronních modelech zasílání zpráv a vysoké dostupnosti.
Začít můžete s následujícím nastavením operací opakování. Tato nastavení jsou pro obecné účely a měli byste tyto operace monitorovat a vyladit hodnoty tak, aby vyhovovaly vašemu vlastnímu scénáři.
| Kontext | Příklad maximální latence | Zásady opakování | Nastavení | Jak to funguje |
|---|---|---|---|---|
| Interaktivní, uživatelské rozhraní nebo popředí | 2 sekundy* | Exponenciální | MinimumBackoff = 0 MaximumBackoff = 30 s DeltaBackoff = 300 ms TimeBuffer = 300 ms MaxRetryCount = 2 |
Pokus 1: zpoždění 0 s Pokus 2: zpoždění ~300 ms Pokus 3: zpoždění ~900 ms |
| Pozadí nebo dávka | 30 sekund | Exponenciální | MinimumBackoff = 1 MaximumBackoff = 30 s DeltaBackoff = 1,75 s TimeBuffer = 5 s MaxRetryCount = 3 |
Pokus 1: zpoždění ~1 s Pokus 2: zpoždění ~3 s Pokus 3: Zpoždění ~6 s Pokus 4: Zpoždění ~13 s |
* Nezahrnuje další zpoždění, které se přidá při přijetí odpovědi ServerBusy.
Telemetrie
Service Bus protokoluje opakované pokusy jako události Trasování událostí pro Windows s použitím EventSource. Ke zdroji událostí musíte připojit EventListener, abyste události zachytili a zobrazili v nástroji Performance Viewer nebo je zapisovali do vhodného cílového protokolu. Události opakování mají následující podobu:
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"
Příklady
Následující příklad kódu ukazuje, jak nastavit zásady opakování pro:
- Namespace Manager. Zásady platí pro všechny operace na tomto Namespace Manageru a nedají se přepsat pro jednotlivé operace.
- Messaging Factory. Zásady platí pro všechny klienty vytvořené z této Messaging Factory a nedají se přepsat při vytváření jednotlivých klientů.
- Jednotlivého klienta zasílání zpráv. Po vytvoření klienta můžete nastavit zásady opakování pro tohoto klienta. Tyto zásady platí pro všechny operace na tomto klientovi.
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();
}
}
}
}
Další informace
Service Fabric
Při distribuci spolehlivých služeb v clusteru Service Fabric budete chráněni před většinou potenciálních přechodných chyb popisovaných v tomto článku. Některé přechodné chyby jsou ale přesto možné. Když například služba pojmenování obdrží žádost během změny směrování, vyvolá výjimku. Pokud stejná žádost přijde o 100 milisekund později, bude pravděpodobně úspěšná.
Service Fabric spravuje tento druh přechodné chyby interně. Při nastavování služeb můžete některá nastavení nakonfigurovat pomocí třídy OperationRetrySettings. Příklad ukazuje následující kód. Ve většině případů by to nemělo být nutné a výchozí nastavení by mělo vyhovovat.
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));
Další informace
SQL Database pomocí ADO.NET
SQL Database je hostovaná databáze SQL, která je dostupná v různých velikostech a jako standardní (sdílená) nebo premium (nesdílená) služba.
Mechanismus opakování
SQL Database nemá předdefinovanou podporu opakovaných pokusů při přístupu pomocí ADO.NET. Pomocí návratových kódů žádostí se ale dá zjistit, proč žádost selhala. Další informace o omezování u SQL Database najdete v článku Limity prostředků Azure SQL Database. Seznam příslušných kódů chyb najdete v článku Kódy chyb SQL pro klientské aplikace SQL Database.
K implementaci opakovaných pokusů u SQL Database můžete použít knihovnu Polly. Podívejte se na část Zpracování přechodných chyb pomocí knihovny Polly.
Pokyny k použití opakování
Když budete přistupovat k SQL Database pomocí ADO.NET, vezměte v úvahu následující pokyny:
- Zvolte patřičnou možnost služby (sdílenou nebo premium službu). Sdílená instance může trpět prodlevami připojení delšími než obvykle a omezeními v důsledku použití dalšími tenanty sdíleného serveru. Pokud požadujete předvídatelný výkon a spolehlivé operace s nízkou latencí, zvažte volbu možnosti premium.
- Zajistěte, aby opakované pokusy probíhaly v patřičné úrovni nebo rozsahu, abyste zabránili neidempotentním operacím způsobujícím nekonzistenci dat. V ideálním případě by všechny operace měly být idempotentní, aby se mohly opakovat bez rizika, že způsobí nekonzistenci. Pokud tomu tak není, mělo by se opakování provádět v úrovni nebo rozsahu, který umožňuje v případě selhání jedné operace vrátit zpět všechny související změny (například z oboru transakce). Další informace najdete v článku Vrstva přístupu k datům u aplikace Cloud Service Fundamentals – zpracování přechodných chyb.
- Strategie s pevným intervalem se pro použití s Azure SQL Database nedoporučuje – s výjimkou interaktivních scénářů, u kterých je jenom pár opakovaných pokusů s velmi krátkými intervaly. Místo toho zvažte pro většinu scénářů použití exponenciální regresní strategie.
- Při definování připojení zvolte vhodnou hodnotu časových limitů připojení a příkazů. Příliš krátký časový limit může u přetížené databáze vést k předčasným chybám. Příliš dlouhý časový limit může bránit správnému fungování logiky opakování, která bude příliš dlouho čekat, než zjistí neúspěšné připojení. Hodnota časového limitu je součástí celkové latence – fakticky se pro každý opakovaný pokus přidává ke zpoždění opakování určenému v zásadách opakování.
- Ukončete připojení po určitém počtu opakovaných pokusů, i když používáte exponenciální regresní logiku opakování, a opakujte operaci u nového připojení. Vícenásobné opakování stejné operace u stejného připojení může přispívat k problémům s připojením. Příklad této techniky najdete v článku Vrstva přístupu k datům u aplikace Cloud Service Fundamentals – zpracování přechodných chyb.
- Když se používá sdružování připojení (ve výchozím nastavení), může se stát, že se z fondu vybere stejné připojení, a to i po zavření a znovuotevření připojení. Pokud se jedná o tento případ, dá se to řešit tak, že se zavolá metoda ClearPool třídy SqlConnection a připojení se označí jako opětovně nepoužitelné. Mělo by se to ale udělat až po několika neúspěšných pokusech o připojení a jenom v případě určité kategorie přechodných selhání, například u vypršení časových limitů SQL (kód chyby -2) souvisejících s chybnými připojeními.
- Pokud kód pro přístup k datům používá transakce iniciované jako instance TransactionScope, měla by logika opakování znovu otevřít připojení a iniciovat nový obor transakce. Z tohoto důvodu by měl blok opakovatelného kódu zahrnovat celý obor transakce.
Začít můžete s následujícím nastavením operací opakování. Tato nastavení jsou pro obecné účely a měli byste monitorovat operace a vyladit hodnoty tak, aby vyhovovaly vašemu scénáři.
| Kontext | Vzorová max. cílová latence E2E |
Strategie opakování | Nastavení | Hodnoty | Jak to funguje |
|---|---|---|---|---|---|
| Interaktivní, uživatelské rozhraní nebo popředí |
2 s | FixedInterval | Počet opakování Interval opakování První rychlé opakování |
3 500 ms true |
Pokus 1 – zpoždění 0 s Pokus 2 – zpoždění 500 ms Pokus 3 – zpoždění 500 ms |
| Pozadí nebo dávka |
30 s | ExponentialBackoff | Počet opakování Min back-off Max back-off Delta back-off První rychlé opakování |
5 0 s 60 s 2 s false (nepravda) |
Pokus 1 – zpoždění 0 s Pokus 2 – zpoždění ~2 s Pokus 3 – zpoždění ~6 s Pokus 4 – zpoždění ~14 s Pokus 5 – zpoždění ~30 s |
Poznámka
Cílové hodnoty celkové latence předpokládají výchozí časový limit pro připojení ke službě. Pokud zadáte delší časové limity připojení, celková latence se pro každý opakovaný pokus prodlouží o tuto další dobu.
Příklady
Tato část ukazuje, jak můžete použít knihovnu Polly pro přístup k Azure SQL Database pomocí sady zásad opakování nakonfigurovaných v třídě Policy.
Následující kód ukazuje rozšiřující metodu u třídy SqlCommand, která volá ExecuteAsync s exponenciální regresí.
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);
}
Tato asynchronní rozšiřující metoda se dá použít následovně.
var sqlCommand = sqlConnection.CreateCommand();
sqlCommand.CommandText = "[some query]";
using (var reader = await sqlCommand.ExecuteReaderWithRetryAsync())
{
// Do something with the values
}
Další informace
obecné informace o tom, jak získat maximum z SQL Database, najdete v tématu Azure SQL Database výkon a příručka pro pružnost.
SQL Database s využitím Entity Framework 6
SQL Database je hostovaná databáze SQL, která je dostupná v různých velikostech a jako standardní (sdílená) nebo premium (nesdílená) služba. Entity Framework je objektově-relační mapovač, který umožňuje vývojářům na platformě .NET pracovat s relačními daty pomocí objektů specifických pro doménu. Šetří vývojářům práci, protože nemusejí psát většinu kódu pro přístup k datům.
Mechanismus opakování
pokud se přistupujete k SQL Database pomocí Entity Framework 6,0 a vyššího pomocí mechanismu nazývaného odolnost proti chybám připojení/opakování, je k dispozici podpora opakování. Hlavní funkce mechanismu opakování jsou:
- Primární abstrakcí je rozhraní IDbExecutionStrategy. Toto rozhraní:
- Definuje synchronní a asynchronní metody Execute .
- Definuje třídy, které se dají použít přímo nebo se dají konfigurovat pro kontext databáze jako výchozí strategie, mapovat na název zprostředkovatele nebo mapovat na název zprostředkovatele a název serveru. Při konfiguraci pro kontext probíhají opakování na úrovni jednotlivých databázových operací, z nichž některé můžou být pro danou kontextovou operaci.
- Definuje, kdy a jak se má neúspěšné připojení opakovat.
- Zahrnuje několik předdefinovaných implementací rozhraní IDbExecutionStrategy:
- Výchozí: žádné opakování.
- výchozí pro SQL Database (automaticky): žádné opakování, ale zkontroluje výjimky a zabalí je s návrhy na použití SQL Database strategie.
- výchozí pro SQL Database: exponenciální (zděděné ze základní třídy) a SQL Database logiku detekce.
- Implementuje exponenciální regresní strategii, která zahrnuje náhodnost.
- Předdefinované třídy opakování jsou stavové a nejsou bezpečné pro přístup z více vláken. Můžou ale být znovu použité po dokončení aktuální operace.
- Pokud se překročí určený počet opakování, zabalí se výsledky do nové výjimky. Nedojde k „vývěru“ aktuální výjimky.
Konfigurace zásad
Opakování je podporované při přístupu k SQL Database pomocí technologie Entity Framework 6.0 nebo vyšší. Zásady opakování se konfigurují programově. Konfigurace se nedá měnit pro každou operaci zvlášť.
Když konfigurujete strategii pro kontext jako výchozí, určíte funkci, která vytvoří novou strategii na vyžádání. Následující kód ukazuje, jak můžete vytvořit třídu konfigurace opakování, která rozšiřuje základní třídu DbConfiguration.
public class BloggingContextConfiguration : DbConfiguration
{
public BlogConfiguration()
{
// Set up the execution strategy for SQL Database (exponential) with 5 retries and 4 sec delay
this.SetExecutionStrategy(
"System.Data.SqlClient", () => new SqlAzureExecutionStrategy(5, TimeSpan.FromSeconds(4)));
}
}
Tuto konfiguraci pak můžete při spuštění aplikace určit jako výchozí strategii opakování pro všechny operace pomocí metody SetConfiguration instance DbConfiguration. Entity Framework (EF) ve výchozím nastavení tuto třídu konfigurace automaticky zjistí a použije.
DbConfiguration.SetConfiguration(new BloggingContextConfiguration());
Třídu konfigurace opakování můžete pro kontext určit její anotací pomocí atributu DbConfigurationType. Pokud ale máte jenom jednu třídu konfigurace, Entity Framework ji použije, i když nebudete kontext anotovat.
[DbConfigurationType(typeof(BloggingContextConfiguration))]
public class BloggingContext : DbContext
Pokud potřebujete pro určité operace použít jiné strategie opakování nebo opakování zakázat, můžete vytvořit třídu konfigurace, která umožňuje pozastavit nebo přepnout strategie nastavením příznaku v CallContext. Tato třída konfigurace může tento příznak použít k přepnutí strategií nebo k zákazu vámi poskytnuté strategie a k použití výchozí strategie. Další informace najdete v tématu pozastavení provádění strategie (EF6 a vyšší).
Další možností, jak používat pro jednotlivé operace zvláštní strategie opakování, je vytvoření instance požadované třídy strategie a předání potřebných nastavení pomocí parametrů. Pak vyvoláte její metodu 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()
);
Nejjednodušší způsob použití třídy DbConfiguration je její umístění ve stejném sestavení, ve kterém je třída DbContext. To ale není přijatelné, pokud je stejný kontext požadovaný v různých scénářích, například u různých interaktivních strategií a strategií opakování na pozadí. Pokud se různé kontexty provádějí v samostatných doménách aplikace, můžete využít předdefinovanou podporu k určení tříd konfigurace v konfiguračním souboru nebo provést nastavení explicitně pomocí kódu. Pokud se různé kontexty musí provádět ve stejné doméně aplikace, bude nutné vlastní řešení.
Další informace najdete v tématu Konfigurace na základě kódu (EF6 a vyšší).
Následující tabulka ukazuje výchozí nastavení pro předdefinované zásady opakování při použití EF6.
| Nastavení | Výchozí hodnota | Význam |
|---|---|---|
| Zásady | Exponenciální | Exponenciální regresní. |
| MaxRetryCount | 5 | Maximální počet opakování. |
| MaxDelay | 30 sekund | Maximální zpoždění mezi opakovanými pokusy. Tato hodnota nemá vliv na to, jak se počítají řady zpoždění. Jenom definuje horní mez. |
| DefaultCoefficient | 1 sekunda | Koeficient pro exponenciální regresní výpočet. Tato hodnota se nedá změnit. |
| DefaultRandomFactor | 1.1 | Násobitel používaný k přidání náhodného zpoždění ke každé položce. Tato hodnota se nedá změnit. |
| DefaultExponentialBase | 2 | Násobitel používaný k výpočtu dalšího zpoždění. Tato hodnota se nedá změnit. |
Pokyny k použití opakování
Když budete přistupovat k SQL Database pomocí EF6, vezměte v úvahu následující pokyny:
Zvolte patřičnou možnost služby (sdílenou nebo premium službu). Sdílená instance může trpět prodlevami připojení delšími než obvykle a omezeními v důsledku použití dalšími tenanty sdíleného serveru. Pokud požadujete předvídatelný výkon a spolehlivé operace s nízkou latencí, zvažte volbu možnosti premium.
Strategie s pevným intervalem se pro použití s Azure SQL Database nedoporučuje. Místo ní použijte exponenciální regresní strategii, protože služba může být přetížená a delší prodlevy jí dají více času na zotavení.
Při definování připojení zvolte vhodnou hodnotu časových limitů připojení a příkazů. Časový limit založte na návrhu obchodní logiky a testování. Tuto hodnotu budete možná muset v průběhu času měnit, jak se budou měnit objemy dat nebo obchodní procesy. Příliš krátký časový limit může u přetížené databáze vést k předčasným chybám. Příliš dlouhý časový limit může bránit správnému fungování logiky opakování, která bude příliš dlouho čekat, než zjistí neúspěšné připojení. Hodnota časového limitu je součástí celkové latence, nedá se ale snadno určit, kolik příkazů se při ukládání kontextu provede. Výchozí časový limit můžete změnit nastavením vlastnosti CommandTimeout instance DbContext.
Entity Framework podporuje konfigurace definované v konfiguračních souborech. Kvůli maximální flexibilitě v Azure byste ale měli zvážit programové vytvoření konfigurace v rámci aplikace. Konkrétní parametry zásad opakování, jako třeba počet opakování nebo intervaly opakování, můžou být uložené v konfiguračním souboru služby. V době běhu aplikace můžou být použité k vytvoření patřičných zásad. Tak je možné nastavení změnit bez restartování aplikace.
Začít můžete s následujícím nastavením operací opakování. Prodlevu mezi opakovanými pokusy nemůžete určit (je pevná a generuje se jako exponenciální posloupnost). Můžete určit jenom maximální hodnoty, jak je ukázáno níže (pokud nevytvoříte vlastní strategii opakování). Tato nastavení jsou pro obecné účely a měli byste tyto operace monitorovat a vyladit hodnoty tak, aby vyhovovaly vašemu vlastnímu scénáři.
| Kontext | Vzorová max. cílová latence E2E |
Zásady opakování | Nastavení | Hodnoty | Jak to funguje |
|---|---|---|---|---|---|
| Interaktivní, uživatelské rozhraní nebo popředí |
2 sekundy | Exponenciální | MaxRetryCount MaxDelay |
3 750 ms |
Pokus 1 – zpoždění 0 s Pokus 2 – zpoždění 750 ms Pokus 3 – zpoždění 750 ms |
| Pozadí nebo dávka |
30 sekund | Exponenciální | MaxRetryCount MaxDelay |
5 12 sekund |
Pokus 1 – zpoždění 0 s Pokus 2 – zpoždění ~1 s Pokus 3 – zpoždění ~3 s Pokus 4 – zpoždění ~7 s Pokus 5 – zpoždění 12 s |
Poznámka
Cílové hodnoty celkové latence předpokládají výchozí časový limit pro připojení ke službě. Pokud zadáte delší časové limity připojení, celková latence se pro každý opakovaný pokus prodlouží o tuto další dobu.
Příklady
Následující příklad kódu definuje jednoduché řešení přístupu k datům, které používá Entity Framework. Nastaví zvláštní strategii opakování definováním instance třídy s názvem BlogConfiguration, která rozšiřuje 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();
}
}
}
}
Další příklady použití mechanismu Entity Frameworkho opakování najdete v logice připojení/opakování.
Další informace
SQL Database pomocí Entity Framework Core
Entity Framework Core je objektově-relační mapovač, který umožňuje vývojářům na platformě .NET Core pracovat s daty pomocí objektů specifických pro doménu. Šetří vývojářům práci, protože nemusejí psát většinu kódu pro přístup k datům. Tato verze Entity Framework byla napsaná od základu – nezdědila automaticky všechny funkce EF6.x.
Mechanismus opakování
při přístupu k SQL Database pomocí Entity Framework Core prostřednictvím mechanismu nazývaného odolnost připojeníse poskytuje opakovaná podpora. Odolnost připojení byla zavedená v EF Core 1.1.0.
Primární abstrakcí je rozhraní IExecutionStrategy. Strategie provádění pro SQL Server, včetně SQL Azure, rozeznává typy výjimek, které se můžou opakovat, a má účelné výchozí hodnoty maximálních počtů opakování, zpoždění mezi opakováními a tak dál.
Příklady
Následující kód umožní automatické opakování pokusů – při konfiguraci objektu DbContext, který reprezentuje relaci s databází.
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer(
@"Server=(localdb)\mssqllocaldb;Database=EFMiscellaneous.ConnectionResiliency;Trusted_Connection=True;",
options => options.EnableRetryOnFailure());
}
Následující kód ukazuje, jak se provádí transakce s automatickým opakováním pokusů – s použitím strategie provádění. Transakce je definovaná v delegátovi. Pokud dojde k přechodnému selhání, strategie provádění znovu vyvolá delegáta.
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
mezi Azure Storage služby patří úložiště objektů blob, soubory a fronty úložiště.
Objekty blob, fronty a soubory
Třída ClientOptions je základní typ pro všechny typy možností klienta a zpřístupňuje různé běžné možnosti klienta, jako je diagnostika, opakování a přenos. k poskytnutí možností konfigurace klienta pro připojení k frontě Azure, objektu Blob a File Storage musíte použít odpovídající odvozený typ. V následujícím příkladu použijete třídu QueueClientOptions (odvozenou od ClientOptions) ke konfiguraci klienta pro připojení ke službě Azure Queue Service. Vlastnost opakování je sada možností, které je možné určit, aby ovlivnila způsob, jakým se provádí pokusy o opakování, a způsob, jakým může být selhání možné opakovat.
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);
Podpora tabulek
Poznámka
WindowsAzure. Storage Balíček NuGet se už nepoužívá. Podporu tabulek Azure najdete v tématu Microsoft. Azure. Cosmos. Balíček NuGet tabulky
Mechanismus opakování
Opakování probíhají na úrovni jednotlivých operací REST a jsou nedílnou součástí klientského rozhraní API. Sada SDK klientského úložiště používá třídy, které implementují rozhraní IExtendedRetryPolicy.
Předdefinované třídy podporují lineární (s konstantním zpožděním) a exponenciální strategii opakování s náhodně modifikovanými intervaly opakování. Když se o opakování stará jiný proces na vyšší úrovni, dají se také použít zásady bez opakování. Pokud máte zvláštní požadavky, které se nedají splnit pomocí předdefinovaných tříd, můžete implementovat svoje vlastní třídy opakování.
Pokud používáte geografické redundantní úložiště s přístupem pro čtení (RA-GRS) a výsledkem žádosti je chyba řešitelná opakováním, opakování se střídavě přepínají mezi primární a sekundární lokalitou služby úložiště. Další informace najdete v článku Možnosti redundance Azure Storage.
Konfigurace zásad
Zásady opakování se konfigurují programově. Obvykle se postupuje tak, že se vytvoří a naplní instance TableRequestOptions, BlobRequestOptions, FileRequestOptions nebo QueueRequestOptions.
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)
};
Pro klienta se pak dá nastavit instance možností žádosti a všechny operace s klientem budou používat určené možnosti žádosti.
client.DefaultRequestOptions = interactiveRequestOption;
var stats = await client.GetServiceStatsAsync();
Možnosti žádosti klienta se dají přepsat tím, že se metodám operace předá jako parametr naplněná instance třídy možností žádosti.
var stats = await client.GetServiceStatsAsync(interactiveRequestOption, operationContext: null);
Pomocí instance OperationContext můžete určit kód, který se má provést, když dojde k opakování a když je operace dokončená. Tento kód může shromažďovat informace o operaci k použití v protokolech a telemetrii.
// 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);
Rozšířené zásady opakování kromě toho, že indikují, jestli je selhání vhodné k nápravě opakováním, vracejí také objekt RetryContext, který indikuje počet opakování, výsledky poslední žádosti a jestli k příštímu pokusu dojde v primární nebo sekundární lokalitě (podrobnosti obsahuje níže uvedená tabulka). Pomocí vlastností objektu RetryContext se dá rozhodnout, jestli a kdy se pokusit o opakování. Další informace naleznete v tématu Metoda IExtendedRetryPolicy. Evaluate.
Následující tabulky ukazují výchozí nastavení pro předdefinované zásady opakování.
Možnosti žádosti:
| Nastavení | Výchozí hodnota | Význam |
|---|---|---|
| MaximumExecutionTime | Žádné | Maximální doba na provedení žádosti, včetně všech možných opakovaných pokusů. Pokud není zadaný, doba, po kterou je požadavek povolený, je neomezená. Jinými slovy, požadavek může přestat reagovat. |
| ServerTimeout | Žádné | Interval časového limitu serveru pro žádost (hodnota je zaokrouhlená na sekundy). Pokud není tato hodnota zadaná, použije se pro všechny žádosti na server výchozí hodnota. Nejlepší možností je obvykle toto nastavení vynechat, aby se použila výchozí hodnota serveru. |
| LocationMode | Žádné | Pokud je účet úložiště vytvořený s možností replikace Geografické redundantní úložiště s přístupem pro čtení (RA-GRS), můžete pomocí LocationMode nastavit, která lokalita má obdržet žádost. Pokud je třeba nastavené PrimaryThenSecondary, budou se žádosti vždy odesílat nejdříve do primární lokality. Pokud bude žádost neúspěšná, odešle se do sekundární lokality. |
| RetryPolicy | ExponentialPolicy | Podrobnosti k jednotlivým možnostem jsou uvedené níže. |
Exponenciální zásady:
| Nastavení | Výchozí hodnota | Význam |
|---|---|---|
| maxAttempt | 3 | Počet opakovaných pokusů. |
| deltaBackoff | 4 sekundy | Regresní interval mezi opakovanými pokusy. Pro následující opakované pokusy se použijí násobky tohoto časového rozsahu, včetně náhodného prvku. |
| MinBackoff | 3 sekundy | Přidává se ke všem intervalům opakování vypočítaným z hodnoty deltaBackoff. Tato hodnota se nedá změnit. |
| MaxBackoff | 120 sekund | Hodnota MaxBackoff se použije, pokud je vypočítaný interval opakování větší než MaxBackoff. Tato hodnota se nedá změnit. |
Lineární zásady:
| Nastavení | Výchozí hodnota | Význam |
|---|---|---|
| maxAttempt | 3 | Počet opakovaných pokusů. |
| deltaBackoff | 30 sekund | Regresní interval mezi opakovanými pokusy. |
Pokyny k použití opakování
Když budete přistupovat ke službám úložiště Azure pomocí rozhraní API klienta úložiště, vezměte v úvahu následující pokyny:
Použijte předdefinované zásady opakování z Microsoft. Azure. Storage. RetryPolicies obor názvů, kde jsou vhodné pro vaše požadavky. Tyto zásady budou ve většině případů dostatečné.
V dávkových operacích, v úlohách na pozadí a v neinteraktivních scénářích použijte zásady ExponentialRetry. V těchto scénářích můžete obvykle umožnit více času, aby se služba obnovila — s tím, že se tím zvýší šance na to, že operace bude nakonec úspěšná.
Zvažte zadání vlastnosti MaximumExecutionTime parametru RequestOptions k omezení celkové doby provádění, ale při volbě časového limitu vezměte v úvahu typ a velikost operace.
Pokud potřebujete implementovat vlastní opakování, nevytvářejte obálky kolem tříd klienta úložiště. Místo toho použijte možnosti k rozšíření stávajících zásad prostřednictvím rozhraní IExtendedRetryPolicy.
Pokud používáte geografické redundantní úložiště s přístupem pro čtení (RA-GRS), můžete použít možnost LocationMode a nastavit, aby opakované pokusy v případě neúspěšného přístupu k primární lokalitě přistupovaly k sekundární kopii úložiště, která je jen pro čtení. Při použití této možnosti ale musíte zajistit, aby vaše aplikace úspěšně pracovala s daty, která můžou být zastaralá (v případě, že ještě nebyla dokončená replikace z primárního úložiště).
Začít můžete s následujícím nastavením operací opakování. Tato nastavení jsou pro obecné účely a měli byste tyto operace monitorovat a vyladit hodnoty tak, aby vyhovovaly vašemu vlastnímu scénáři.
| Kontext | Vzorová max. cílová latence E2E |
Zásady opakování | Nastavení | Hodnoty | Jak to funguje |
|---|---|---|---|---|---|
| Interaktivní, uživatelské rozhraní nebo popředí |
2 sekundy | Lineární | maxAttempt deltaBackoff |
3 500 ms |
Pokus 1 – zpoždění 500 ms Pokus 2 – zpoždění 500 ms Pokus 3 – zpoždění 500 ms |
| Pozadí nebo dávka |
30 sekund | Exponenciální | maxAttempt deltaBackoff |
5 4 sekundy |
Pokus 1 – zpoždění ~3 s Pokus 2 – zpoždění ~7 s Pokus 3 – zpoždění ~15 s |
Telemetrie
Opakované pokusy se protokolují do TraceSource. Je nutné nakonfigurovat TraceListener k zachycení událostí a jejich zápisu do vhodného cílového protokolu. TextWriterTraceListener nebo XmlWriterTraceListener můžete použít k zápisu dat do souboru protokolu, EventLogTraceListener k zápisu do protokolu událostí systému Windows a EventProviderTraceListener k zápisu dat trasování do subsystému Trasování událostí pro Windows. Můžete také nakonfigurovat autovyprazdňování vyrovnávací paměti a podrobnost událostí, které budou protokolovány (například chyba, upozornění, informativní a podrobné). Další informace najdete v článku Protokolování na straně klienta s klientskou knihovnou pro úložiště .NET.
Operace můžou přijímat instanci OperationContext, která zveřejňuje událost Retrying – ta se dá použít k připojení vlastní telemetrické logiky. Další informace najdete v článku Událost OperationContext.Retrying.
Příklady
Následující příklad kódu ukazuje, jak vytvořit dvě instance TableRequestOptions s různým nastavením opakování – jednu pro interaktivní žádosti a jednu pro žádosti na pozadí. V příkladu se potom tyto dvě zásady opakování nastaví pro klienta, aby platily pro všechny žádosti. Také se nastaví interaktivní strategie pro konkrétní žádost a přepíše se tak výchozí nastavení použité pro klienta.
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);
}
}
}
}
Další informace
Obecné pokyny pro REST a opakování
Při přístupu ke službám Azure nebo třetích stran Vezměte v úvahu následující:
Při správě opakovaných pokusů používejte systémový přístup, například opakovaně použitelný kód, abyste mohli u všech klientů a řešení použít jednotnou metodologii.
Zvažte použití architektury opakování, jako je Polly , ke správě opakování, pokud cílová služba nebo klient nemá žádný vestavěný mechanismus opakování. To vám umožní implementovat konzistentní chování opakování a může poskytnout vhodnou výchozí strategii opakování pro cílovou službu. Pro služby, které mají nestandardní chování, ale možná budete muset vytvořit vlastní kód opakování, který nespoléhá na výjimky, aby označovala přechodná selhání, nebo pokud chcete použít odpověď na opakovanou odezvu ke správě chování opakování.
Logika zjišťování přechodných chyb bude záviset na skutečném rozhraní API klienta, které budete používat k voláním REST. Někteří klienti, třeba novější třída HttpClient, nebudou vyvolávat výjimky pro dokončené žádosti s neúspěšným stavovým kódem HTTP.
Stavový kód HTTP vrácený službou umožňuje signalizovat, jestli je selhání přechodné. Nejspíš budete muset zkoumat výjimky generované klientem nebo architekturou opakování, abyste získali přístup ke stavovému kódu nebo určili ekvivalentní typ výjimky. Následující kódy HTTP obvykle signalizují, že je opakování vhodné:
- 408 – Časový limit žádosti
- 429 – Příliš mnoho požadavků
- 500 – Vnitřní chyba serveru
- 502 – Chybná brána
- 503 – Nedostupná služba
- 504 – Časový limit brány
Pokud máte logiku opakování založenou na výjimkách a nedá se navázat připojení, následující výjimky obvykle signalizují přechodné selhání:
- WebExceptionStatus.ConnectionClosed
- WebExceptionStatus.ConnectFailure
- WebExceptionStatus.Timeout
- WebExceptionStatus.RequestCanceled
V případě stavu Nedostupná služba může služba indikovat patřičné zpoždění před opakováním v hlavičce odpovědi Retry-After nebo v jiné vlastní hlavičce. Služby také můžou odesílat další informace jako vlastní hlavičky nebo vložené v obsahu odpovědi.
Neopakovat pro stavové kódy, které představují chyby klienta (chyby v rozsahu 4xx) s výjimkou vypršení časového limitu požadavku 408 a 429 příliš mnoho požadavků.
Důkladně otestujte strategie a mechanismy opakování při různých podmínkách, například při různých stavech sítě a měnících se zatíženích systému.
Strategie opakování
Toto jsou obvyklé typy strategií opakování podle intervalů mezi opakovanými pokusy:
Exponenciální. Zásada opakování, která provede zadaný počet opakování pomocí náhodného exponenciálního přístupu k určení intervalu mezi opakováními. Příklad:
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);Přírůstková. Strategie opakování se zadaným počtem opakovaných pokusů a přírůstkovým časovým intervalem mezi opakovanými pokusy. Příklad:
retryInterval = TimeSpan.FromMilliseconds(this.initialInterval.TotalMilliseconds + (this.increment.TotalMilliseconds * currentRetryCount));LinearRetry. Zásada opakování, která provede zadaný počet opakování s použitím zadaného pevného časového intervalu mezi opakovanými pokusy. Příklad:
retryInterval = this.deltaBackoff;
Zpracování přechodných chyb pomocí knihovny Polly
Polly je knihovna pro programové zpracování opakovaných pokusů a strategií přestávek okruhů . Projekt Polly patří organizaci .NET Foundation. Polly je platnou alternativou pro služby, u kterých klient nepodporuje nativně opakované pokusy. Díky knihovně Polly nemusíte psát vlastní kód opakování, jehož správná implementace může být obtížná. Polly také nabízí možnost trasování chyb, takže můžete opakované pokusy protokolovat.