Aracılığıyla paylaş


gRPC yeniden denemeleriyle geçici hata işleme

Yayınlayan James Newton-King

gRPC yeniden denemeleri, gRPC istemcilerinin başarısız çağrıları otomatik olarak yeniden denemesine olanak tanıyan bir özelliktir. Bu makalede, .NET'te dayanıklı, hataya dayanıklı gRPC uygulamaları oluşturmak için bir yeniden deneme ilkesinin nasıl yapılandırılacağı açıklanır.

gRPC yeniden denemeleri için Grpc.Net.Client sürüm 2.36.0 veya üzeri gerekir.

Geçici hata işleme

gRPC çağrıları geçici hatalarla kesilebilir. Geçici hatalar şunlardır:

  • Ağ bağlantısının anlık kaybı.
  • Bir hizmetin geçici olarak kullanılamaz duruma gelmesine neden olabilir.
  • Sunucu yükü nedeniyle zaman aşımları.

Bir gRPC çağrısı kesildiğinde, istemci hatayla ilgili ayrıntıları içeren bir RpcException oluşturur. İstemci uygulamasının özel durumu yakalaması ve hatanın nasıl işleneceğini seçmesi gerekir.

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

Bir uygulama genelinde yeniden deneme mantığını yinelemek ayrıntılıdır ve hataya açıktır. Neyse ki .NET gRPC istemcisi, otomatik yeniden denemeler için yerleşik bir desteğe sahiptir.

gRPC yeniden deneme ilkesini yapılandırma

Bir gRPC kanalı oluşturulduğunda yeniden deneme ilkesi bir kez yapılandırılır:

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

Önceki kod:

  • oluşturur MethodConfig. Yeniden deneme ilkeleri yöntem başına yapılandırılabilir ve yöntemler özelliği kullanılarak Names eşleştirilir. Bu yöntem ile MethodName.Defaultyapılandırıldığından, bu kanal tarafından çağrılan tüm gRPC yöntemlerine uygulanır.
  • Yeniden deneme ilkesi yapılandırılır. Bu ilke, istemcilere durum koduyla Unavailablebaşarısız olan gRPC çağrılarını otomatik olarak yeniden denemelerini sağlar.
  • ayarıyla GrpcChannelOptions.ServiceConfigoluşturulan kanalı yeniden deneme ilkesini kullanacak şekilde yapılandırıyor.

Kanalla oluşturulan gRPC istemcileri başarısız çağrıları otomatik olarak yeniden dener:

var client = new Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(
    new HelloRequest { Name = ".NET" });

Console.WriteLine("From server: " + response.Message);

Yeniden denemeler geçerli olduğunda

Aramalar şu durumlarda yeniden deneniyor:

  • Başarısız olan durum kodu içindeki RetryableStatusCodesbir değerle eşleşir.
  • Önceki deneme sayısı değerinden MaxAttemptsküçüktür.
  • Arama işlenmedi.
  • Son tarih aşılmadı.

gRPC çağrısı iki senaryoda işlenir:

  • İstemci yanıt üst bilgilerini alır. Yanıt üst bilgileri çağrıldığında ServerCallContext.WriteResponseHeadersAsync veya ilk ileti sunucu yanıt akışına yazıldığında sunucu tarafından gönderilir.
  • İstemcinin giden iletisi (veya akış varsa iletiler) istemcinin en büyük arabellek boyutunu aştı. MaxRetryBufferSizeve MaxRetryBufferPerCallSize kanalda yapılandırılır.

Kabul edilen çağrılar, durum kodundan veya önceki deneme sayısından bağımsız olarak yeniden denemez.

Akış çağrıları

Akış çağrıları gRPC yeniden denemeleriyle kullanılabilir, ancak birlikte kullanıldığında dikkat edilmesi gereken önemli noktalar vardır:

  • Sunucu akışı, çift yönlü akış: Sunucudan birden çok ileti döndüren akış RPC'leri, ilk ileti alındıktan sonra yeniden denemez. Uygulamaların sunucu ve çift yönlü akış çağrılarını el ile yeniden oluşturmak için ek mantık eklemesi gerekir.
  • İstemci akışı, çift yönlü akış: Sunucuya birden çok ileti gönderen akış RPC'leri, giden iletiler istemcinin en yüksek arabellek boyutunu aştıysa yeniden denemez. Maksimum arabellek boyutu yapılandırmayla artırılabilir.

Daha fazla bilgi için bkz . Yeniden denemeler geçerli olduğunda.

Geri alma gecikmesi yeniden deneyin

Yeniden deneme girişimleri arasındaki geri alma gecikmesi , MaxBackoffve BackoffMultiplierile InitialBackoffyapılandırılır. Her seçenek hakkında daha fazla bilgiyi gRPC yeniden deneme seçenekleri bölümünde bulabilirsiniz.

Yeniden deneme girişimleri arasındaki gerçek gecikme rastgeledir. 0 ile geçerli geri çekilme arasındaki rastgele gecikme, bir sonraki yeniden deneme girişiminin ne zaman yapıldığını belirler. Üstel geri alma yapılandırıldığında bile, denemeler arasındaki geçerli geri çekilmeyi artırarak, denemeler arasındaki gerçek gecikmenin her zaman daha büyük olmadığını düşünün. Gecikme, birden çok çağrının yeniden denenmesinin birlikte kümelenmesini ve potansiyel olarak sunucuyu aşırı yüklemesini önlemek için rastgeledir.

Meta verilerle yeniden denemeleri algılama

gRPC yeniden denemeleri meta verilerin varlığıyla grpc-previous-rpc-attempts algılanabilir. Meta grpc-previous-rpc-attempts veriler:

  • Yeniden denenen çağrılara otomatik olarak eklenir ve sunucuya gönderilir.
  • Değer, önceki yeniden deneme denemelerinin sayısını temsil eder.
  • Değer her zaman bir tamsayıdır.

Aşağıdaki yeniden deneme senaryolarını göz önünde bulundurun:

  1. İstemci, sunucuya bir gRPC çağrısı yapar.
  2. Sunucu başarısız olur ve yeniden denenebilir durum kodu yanıtı döndürür.
  3. İstemci gRPC çağrısını yeniden denenir. Daha önce bir deneme olduğundan meta grpc-previous-rpc-attempts veriler değerine 1sahiptir. Meta veriler yeniden denenerek sunucuya gönderilir.
  4. Sunucu başarılı olur ve Tamam'ı döndürür.
  5. İstemci başarılı olduğunu bildirir. grpc-previous-rpc-attempts yanıt meta verilerindedir ve değerine 1sahiptir.

Meta grpc-previous-rpc-attempts veriler ilk gRPC çağrısında mevcut değildir, ilk yeniden deneme için, 12 ikinci yeniden deneme için vb. içindir.

gRPC yeniden deneme seçenekleri

Aşağıdaki tabloda gRPC yeniden deneme ilkelerini yapılandırma seçenekleri açıklanmaktadır:

Seçenek Tanım
MaxAttempts Özgün deneme dahil olmak üzere çağrı denemesi sayısı üst sınırı. Bu değer, varsayılan olarak 5 olarak sınırlanır GrpcChannelOptions.MaxRetryAttempts . Bir değer gereklidir ve 1'den büyük olmalıdır.
InitialBackoff Yeniden deneme girişimleri arasındaki ilk geri alma gecikmesi. 0 ile geçerli geri çekilme arasındaki rastgele gecikme, bir sonraki yeniden deneme girişiminin ne zaman yapıldığını belirler. Her denemeden sonra geçerli geri alma işlemi ile BackoffMultiplierçarpılır. Bir değer gereklidir ve sıfırdan büyük olmalıdır.
MaxBackoff Maksimum geri alma, üstel geri alma büyümesine üst sınır uygular. Bir değer gereklidir ve sıfırdan büyük olmalıdır.
BackoffMultiplier Geri alma, her yeniden deneme denemesinden sonra bu değerle çarpılır ve çarpan 1'den büyük olduğunda katlanarak artar. Bir değer gereklidir ve sıfırdan büyük olmalıdır.
RetryableStatusCodes Durum kodları koleksiyonu. Eşleşen bir durumla başarısız olan bir gRPC çağrısı otomatik olarak yeniden denenir. Durum kodları hakkında daha fazla bilgi için bkz . Durum kodları ve gRPC'de kullanımları. En az bir yeniden denenebilir durum kodu gereklidir.

Hedging

Riskten korunma alternatif bir yeniden deneme stratejisidir. Hedging, yanıt beklemeden tek bir gRPC çağrısının birden çok kopyasının agresif bir şekilde gönderilmesini sağlar. Hedged gRPC çağrıları sunucuda birden çok kez yürütülebilir ve ilk başarılı sonuç kullanılır. Riskten korumanın yalnızca olumsuz etki olmadan birden çok kez yürütülmesi güvenli olan yöntemler için etkinleştirilmesi önemlidir.

Yeniden denemelerle karşılaştırıldığında Hedging'in avantajları ve dezavantajları vardır:

  • Başarılı bir sonucun daha hızlı döndürülmesi, riskten korunmanın bir avantajıdır. Aynı anda birden çok gRPC çağrısına izin verir ve ilk başarılı sonuç kullanılabilir olduğunda tamamlanır.
  • Riskten korunmanın bir dezavantajı, boşa harcanabilir olmasıdır. Birden çok çağrı yapılabilir ve hepsi başarılı olur. Yalnızca ilk sonuç kullanılır ve geri kalanı atılır.

gRPC riskten korunma ilkesi yapılandırma

Bir riskten korunma ilkesi, yeniden deneme ilkesi gibi yapılandırılır. Bir riskten korunma ilkesinin yeniden deneme ilkesiyle birleştirilebileceğini unutmayı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 } }
});

gRPC riskten korunma seçenekleri

Aşağıdaki tabloda gRPC koruma ilkelerini yapılandırma seçenekleri açıklanmaktadır:

Seçenek Tanım
MaxAttempts Riskten korunma ilkesi bu sayıda çağrı gönderir. MaxAttempts , özgün deneme dahil olmak üzere tüm girişimlerin toplam sayısını temsil eder. Bu değer, varsayılan olarak 5 olarak sınırlanır GrpcChannelOptions.MaxRetryAttempts . Bir değer gereklidir ve 2 veya daha büyük olmalıdır.
HedgingDelay İlk çağrı hemen gönderilir, sonraki riskten korunma çağrıları bu değer tarafından geciktirilir. Gecikme sıfır veya nullolarak ayarlandığında, tüm hedged çağrıları hemen gönderilir. HedgingDelay isteğe bağlıdır ve varsayılan olarak sıfırdır. Değer sıfır veya daha büyük olmalıdır.
NonFatalStatusCodes Diğer hedge çağrılarının yine de başarılı olabileceğini gösteren durum kodları koleksiyonu. Sunucu tarafından önemli olmayan bir durum kodu döndürülürse, hedged çağrıları devam eder. Aksi takdirde bekleyen istekler iptal edilir ve hata uygulamaya döndürülür. Durum kodları hakkında daha fazla bilgi için bkz . Durum kodları ve gRPC'de kullanımları.

Ek kaynaklar