Zpracování přechodných chyb pomocí opakování gRPC
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Autor: James Newton-King
Opakování gRPC je funkce, která klientům gRPC umožňuje automaticky opakovat neúspěšná volání. Tento článek popisuje, jak nakonfigurovat zásadu opakování pro zajištění odolnosti aplikací gRPC odolných proti chybám v .NET.
Opakování gRPC vyžaduje Grpc.Net.Client verze 2.36.0 nebo novější.
Zpracování přechodných chyb
Volání gRPC mohou být přerušena přechodnými chybami. Mezi přechodné chyby patří:
- Momentální ztráta síťového připojení.
- Dočasná nedostupnost služby
- Vypršení časových limitů kvůli zatížení serveru
Když dojde k přerušení volání gRPC, klient vyvolá RpcException
podrobnosti o chybě. Klientská aplikace musí zachytit výjimku a zvolit způsob zpracování chyby.
var client = new Greeter.GreeterClient(channel);
try
{
var response = await client.SayHelloAsync(
new HelloRequest { Name = ".NET" });
Console.WriteLine("From server: " + response.Message);
}
catch (RpcException ex)
{
// Write logic to inspect the error and retry
// if the error is from a transient fault.
}
Duplikování logiky opakování v celé aplikaci je podrobné a náchylné k chybám. Klient .NET gRPC má naštěstí integrovanou podporu automatických opakování.
Konfigurace zásad opakování gRPC
Zásady opakování se konfigurují jednou při vytvoření kanálu gRPC:
var defaultMethodConfig = new MethodConfig
{
Names = { MethodName.Default },
RetryPolicy = new RetryPolicy
{
MaxAttempts = 5,
InitialBackoff = TimeSpan.FromSeconds(1),
MaxBackoff = TimeSpan.FromSeconds(5),
BackoffMultiplier = 1.5,
RetryableStatusCodes = { StatusCode.Unavailable }
}
};
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
{
ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }
});
Předchozí kód:
- Vytvoří .
MethodConfig
Zásady opakování lze nakonfigurovat pro jednotlivé metody a metody se shodují pomocíNames
vlastnosti. Tato metoda je nakonfigurovaná takMethodName.Default
, aby byla použita pro všechny metody gRPC volané tímto kanálem. - Nakonfiguruje zásadu opakování. Tato zásada dává klientům pokyn, aby automaticky opakovat volání gRPC, která selžou se stavovým kódem
Unavailable
. - Nakonfiguruje vytvořený kanál tak, aby používal zásadu opakování nastavením
GrpcChannelOptions.ServiceConfig
.
Klienti gRPC vytvořená pomocí kanálu automaticky zopakují neúspěšná volání:
var client = new Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(
new HelloRequest { Name = ".NET" });
Console.WriteLine("From server: " + response.Message);
Pokud jsou opakované pokusy platné
Volání se budou opakovat, když:
- Stavový kód, který selhává, odpovídá hodnotě v
RetryableStatusCodes
. - Předchozí počet pokusů je menší než
MaxAttempts
. - Volání nebylo potvrzeno.
- Konečný termín nebyl překročen.
Volání gRPC se potvrdí ve dvou scénářích:
- Klient obdrží hlavičky odpovědi. Hlavičky odpovědi se odesílají serverem, když
ServerCallContext.WriteResponseHeadersAsync
je volána, nebo při zápisu první zprávy do streamu odpovědí serveru. - Odchozí zpráva klienta (nebo zprávy v případě streamování) překročila maximální velikost vyrovnávací paměti klienta.
MaxRetryBufferSize
aMaxRetryBufferPerCallSize
jsou nakonfigurovány v kanálu.
Potvrzená volání se nebudou opakovat bez ohledu na stavový kód nebo předchozí počet pokusů.
Streamování volání
Volání streamování se dají použít s opakováním gRPC, ale při jejich společném použití je potřeba vzít v úvahu důležité aspekty:
- Streamování serveru, obousměrné streamování: Streamované rpcs, které vrací více zpráv ze serveru, se po přijetí první zprávy znovu nepokusí. Aplikace musí přidat další logiku pro ruční opětovné vytvoření serveru a obousměrných volání streamování.
- Streamování klientů, obousměrné streamování: Streamovací rpc, které odesílají více zpráv na server, se nebudou opakovat, pokud odchozí zprávy překročily maximální velikost vyrovnávací paměti klienta. Maximální velikost vyrovnávací paměti je možné zvýšit pomocí konfigurace.
Další informace naleznete v tématu Kdy jsou pokusy platné.
Zpoždění opakování zpožďování
Zpoždění zpětného odvrácení mezi opakovanými pokusy je nakonfigurováno na InitialBackoff
, MaxBackoff
a BackoffMultiplier
. Další informace o jednotlivých možnostech jsou k dispozici v části možností opakování gRPC.
Skutečné zpoždění mezi opakovanými pokusy je randomizováno. Náhodné zpoždění mezi 0 a aktuálním backoffem určuje, kdy se provede další pokus o opakování. Vezměte v úvahu, že i s nakonfigurovaným exponenciálním zpomalováním a zvýšením aktuálního zpomalování mezi pokusy není skutečné zpoždění mezi pokusy vždy větší. Zpoždění je randomizováno, aby se zabránilo opakování více volání z clusteringu a potenciálně přetížení serveru.
Zjišťování opakovaných pokusů s metadaty
Opakování gRPC je možné zjistit přítomností grpc-previous-rpc-attempts
metadat. Metadata grpc-previous-rpc-attempts
:
- Automaticky se přidá k opakovaným voláním a odešle se na server.
- Hodnota představuje počet předchozích pokusů o opakování.
- Hodnota je vždy celé číslo.
Představte si následující scénář opakování:
- Klient provede volání gRPC na server.
- Server selže a vrátí odpověď stavového kódu, která se dá opakovat.
- Klient opakuje volání gRPC. Protože došlo k jednomu předchozímu pokusu,
grpc-previous-rpc-attempts
metadata mají hodnotu1
. Metadata se posílají na server s opakováním. - Server je úspěšný a vrátí ok.
- Klient hlásí úspěch.
grpc-previous-rpc-attempts
je v metadatech odpovědi a má hodnotu1
.
Metadata grpc-previous-rpc-attempts
nejsou k dispozici při počátečním volání gRPC, jsou 1
pro první opakování, 2
pro druhé opakování atd.
Možnosti opakování gRPC
Následující tabulka popisuje možnosti konfigurace zásad opakování gRPC:
Možnost | Popis |
---|---|
MaxAttempts |
Maximální počet pokusů o volání, včetně původního pokusu. Tato hodnota je omezena GrpcChannelOptions.MaxRetryAttempts výchozím nastavením na hodnotu 5. Hodnota je povinná a musí být větší než 1. |
InitialBackoff |
Počáteční zpoždění zpětného odvrácení mezi pokusy o opakování. Náhodné zpoždění mezi 0 a aktuálním backoffem určuje, kdy se provede další pokus o opakování. Po každém pokusu se aktuální backoff vynásobí BackoffMultiplier hodnotou . Hodnota je povinná a musí být větší než nula. |
MaxBackoff |
Maximální zpochybnění umístí horní mez exponenciálního růstu zpoždnění. Hodnota je povinná a musí být větší než nula. |
BackoffMultiplier |
Backoff se vynásobí touto hodnotou po každém pokusu o opakování a exponenciálně se zvýší, když je násobitel větší než 1. Hodnota je povinná a musí být větší než nula. |
RetryableStatusCodes |
Kolekce stavových kódů. Volání gRPC, které selže s odpovídajícím stavem, se automaticky opakuje. Další informace o stavových kódech naleznete v tématu Stavové kódy a jejich použití v gRPC. Vyžaduje se aspoň jeden stavový kód, který se dá opakovat. |
Uhýbání
Hedging je alternativní strategie opakování. Hedging umožňuje agresivně odesílat více kopií jednoho volání gRPC bez čekání na odpověď. Volání gRPC živého plotu se na serveru můžou spouštět několikrát a použije se první úspěšný výsledek. Je důležité, aby hedgování bylo povoleno pouze pro metody, které jsou bezpečné provádět vícekrát bez nežádoucího účinku.
Hedging má výhody a nevýhody ve srovnání s opakováním:
- Výhodou zajištění je, že může vrátit úspěšný výsledek rychleji. Umožňuje více souběžných volání gRPC a dokončí se, až bude k dispozici první úspěšný výsledek.
- Nevýhodou haldování je, že může být plýtvání. Bylo možné provést více volání a všechny proběhnout úspěšně. Použije se pouze první výsledek a zahodí rest se.
Konfigurace zásad hedgingu gRPC
Zásady hedgingu se konfigurují jako zásady opakování. Všimněte si, že zásady hedgingu nelze kombinovat se zásadami opakování.
var defaultMethodConfig = new MethodConfig
{
Names = { MethodName.Default },
HedgingPolicy = new HedgingPolicy
{
MaxAttempts = 5,
NonFatalStatusCodes = { StatusCode.Unavailable }
}
};
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
{
ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }
});
Možnosti hedgingu gRPC
Následující tabulka popisuje možnosti konfigurace zásad hedgingu gRPC:
Možnost | Popis |
---|---|
MaxAttempts |
Zásady hedgingu budou posílat až tento počet volání. MaxAttempts představuje celkový počet všech pokusů, včetně původního pokusu. Tato hodnota je omezena GrpcChannelOptions.MaxRetryAttempts výchozím nastavením na hodnotu 5. Hodnota je povinná a musí být 2 nebo vyšší. |
HedgingDelay |
První volání se odešle okamžitě, následné volání se zpozdí touto hodnotou. Pokud je zpoždění nastaveno na nulu nebo null , všechny živé volání se odešlou okamžitě. HedgingDelay je volitelné a výchozí hodnota je nula. Hodnota musí být nula nebo větší. |
NonFatalStatusCodes |
Kolekce stavových kódů, které označují další živé volání, může být stále úspěšné. Pokud server vrátí nefaktorový stavový kód, bude pokračovat živé volání. V opačném případě se zruší nevyřízených požadavků a chyba vrácená do aplikace. Další informace o stavových kódech naleznete v tématu Stavové kódy a jejich použití v gRPC. |