Sdílet prostřednictvím


Zpracování přechodných chyb pomocí opakování gRPC

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á tak MethodName.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 a MaxRetryBufferPerCallSize 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, MaxBackoffa 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í:

  1. Klient provede volání gRPC na server.
  2. Server selže a vrátí odpověď stavového kódu, která se dá opakovat.
  3. Klient opakuje volání gRPC. Protože došlo k jednomu předchozímu pokusu, grpc-previous-rpc-attempts metadata mají hodnotu 1. Metadata se posílají na server s opakováním.
  4. Server je úspěšný a vrátí ok.
  5. Klient hlásí úspěch. grpc-previous-rpc-attempts je v metadatech odpovědi a má hodnotu 1.

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

Zajiště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 zbytek se zahodí.

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.

Další prostředky