gRPC yeniden denemeleriyle geçici hata işleme
Uyarı
ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.
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 } }
});
Yukarıdaki kod:
- oluşturur
MethodConfig
. Yeniden deneme ilkeleri yöntem başına yapılandırılabilir ve yöntemler özelliği kullanılarakNames
eşleştirilir. Bu yöntem ileMethodName.Default
yapı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
Unavailable
başarısız olan gRPC çağrılarını otomatik olarak yeniden denemelerini sağlar. - ayarıyla
GrpcChannelOptions.ServiceConfig
oluş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
RetryableStatusCodes
bir değerle eşleşir. - Önceki deneme sayısı değerinden
MaxAttempts
küçü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ı.
MaxRetryBufferSize
veMaxRetryBufferPerCallSize
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 , MaxBackoff
ve BackoffMultiplier
ile InitialBackoff
yapı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:
- İstemci, sunucuya bir gRPC çağrısı yapar.
- Sunucu başarısız olur ve yeniden denenebilir durum kodu yanıtı döndürür.
- İstemci gRPC çağrısını yeniden denenir. Daha önce bir deneme olduğundan meta
grpc-previous-rpc-attempts
veriler değerine1
sahiptir. Meta veriler yeniden denenerek sunucuya gönderilir. - Sunucu başarılı olur ve Tamam'ı döndürür.
- İstemci başarılı olduğunu bildirir.
grpc-previous-rpc-attempts
yanıt meta verilerindedir ve değerine1
sahiptir.
Meta grpc-previous-rpc-attempts
veriler ilk gRPC çağrısında mevcut değildir, ilk yeniden deneme için, 1
2
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 | Açıklama |
---|---|
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 rest 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 | Açıklama |
---|---|
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 null olarak 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
ASP.NET Core