.NET'te gRPC kesişimcileri
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.
Tarafından Ernest Nguyen
Kesiciler, uygulamaların gelen veya giden gRPC çağrılarıyla etkileşim kurmasını sağlayan bir gRPC kavramıdır. İstek işleme işlem hattını zenginleştirmek için bir yol sunar.
Kesiciler bir kanal veya hizmet için yapılandırılır ve her gRPC çağrısı için otomatik olarak yürütülür. Kesme makineleri kullanıcının uygulama mantığına göre saydam olduğundan günlük kaydı, izleme, kimlik doğrulaması ve doğrulama gibi yaygın durumlar için mükemmel bir çözüm sunar.
Interceptor
tür
Kesiciler, türünden Interceptor
devralan bir sınıf oluşturularak hem gRPC sunucuları hem de istemcileri için uygulanabilir:
public class ExampleInterceptor : Interceptor
{
}
Varsayılan olarak, Interceptor
temel sınıf hiçbir şey yapmaz. Bir kesme noktası uygulamasında uygun temel sınıf yöntemlerini geçersiz kılarak bir kesiciye davranış ekleyin.
İstemci kesişimcileri
gRPC istemci kesme makineleri giden RPC çağrılarını durdurur. Gönderilen istek, gelen yanıt ve istemci tarafı çağrısı bağlamı için erişim sağlar.
Interceptor
istemcisini geçersiz kılma yöntemleri:
BlockingUnaryCall
: Birli RPC'nin engelleyici çağrısını durdurur.AsyncUnaryCall
: Birli RPC'nin zaman uyumsuz çağrısını durdurur.AsyncClientStreamingCall
: İstemci akışı RPC'sinin zaman uyumsuz çağrısını durdurur.AsyncServerStreamingCall
: Sunucu akışı RPC'sinin zaman uyumsuz çağrısını durdurur.AsyncDuplexStreamingCall
: Çift yönlü akış RPC'sinin zaman uyumsuz çağrısını durdurur.
Uyarı
Hem hem de BlockingUnaryCall
AsyncUnaryCall
birli RPC'lere başvuruda bulunmakla birlikte, bunlar birbirinin yerine kullanılamaz. Engelleme çağrısı tarafından AsyncUnaryCall
kesilmez ve zaman uyumsuz çağırma bir BlockingUnaryCall
tarafından kesilmez.
İstemci gRPC kesme noktası oluşturma
Aşağıdaki kod, birli çağrının zaman uyumsuz çağrısını kesmenin temel bir örneğini sunar:
public class ClientLoggingInterceptor : Interceptor
{
private readonly ILogger _logger;
public ClientLoggingInterceptor(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<ClientLoggingInterceptor>();
}
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
TRequest request,
ClientInterceptorContext<TRequest, TResponse> context,
AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
{
_logger.LogInformation("Starting call. Type/Method: {Type} / {Method}",
context.Method.Type, context.Method.Name);
return continuation(request, context);
}
}
Geçersiz kılma AsyncUnaryCall
:
- Zaman uyumsuz bir tekli çağrıyı durdurur.
- Aramayla ilgili ayrıntıları günlüğe kaydeder.
- yöntemine
continuation
geçirilen parametresini çağırır. Bu, son kesme noktası ise zincirdeki sonraki kesme noktasını veya temel alınan çağrı çağırıcısını çağırır.
Her tür hizmet yöntemi için üzerindeki Interceptor
yöntemlerin farklı imzaları vardır. Ancak, ve parametrelerinin ardındaki continuation
context
kavram aynı kalır:
continuation
zincirdeki sonraki kesme noktasını veya temel alınan çağrı çağırıcısını çağıran bir temsilcidir (zincirde kesme noktası kalmadıysa). Sıfır veya birden çok kez çağırmak bir hata değildir. Kesme noktalarının temsilciden döndürülen bir çağrı gösterimi (AsyncUnaryCall
birli RPC olması durumunda) döndürmesicontinuation
gerekmez. Temsilci çağrısını atlayıp kendi çağrı gösterimi örneğinizi döndürmek, kesmecilerin zincirini bozar ve ilişkili yanıtı hemen döndürür.context
istemci tarafı çağrısıyla ilişkili kapsamlı değerler taşır. Güvenlik sorumluları, kimlik bilgileri veya izleme verileri gibi meta verileri geçirmek için kullanıncontext
. Ayrıca,context
son tarihler ve iptaller hakkında bilgi taşır. Daha fazla bilgi için bkz . Son tarihler ve iptal ile güvenilir gRPC hizmetleri.
İstemci kesme aracında yanıt bekleniyor
Bir kesme noktası, veya AsyncClientStreamingCall<TRequest, TResponse>.ResponseAsync
değerini güncelleştirerek tekli ve istemci akış çağrılarında AsyncUnaryCall<TResponse>.ResponseAsync
yanıtı bekleyebilirsiniz.
public class ErrorHandlerInterceptor : Interceptor
{
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
TRequest request,
ClientInterceptorContext<TRequest, TResponse> context,
AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
{
var call = continuation(request, context);
return new AsyncUnaryCall<TResponse>(
HandleResponse(call.ResponseAsync),
call.ResponseHeadersAsync,
call.GetStatus,
call.GetTrailers,
call.Dispose);
}
private async Task<TResponse> HandleResponse<TResponse>(Task<TResponse> inner)
{
try
{
return await inner;
}
catch (Exception ex)
{
throw new InvalidOperationException("Custom error", ex);
}
}
}
Yukarıdaki kod:
- öğesini geçersiz kılan
AsyncUnaryCall
yeni bir kesme noktası oluşturur. - Geçersiz kılma
AsyncUnaryCall
:- Kesme noktası zincirindeki
continuation
sonraki öğeyi çağırmak için parametresini çağırır. - Devamlılık sonucuna göre yeni
AsyncUnaryCall<TResponse>
bir örnek oluşturur. - yöntemini kullanarak
HandleResponse
görevi sarmalarResponseAsync
. - ile
HandleResponse
yanıt bekler. Yanıtın beklenmesi, istemci yanıtı aldıktan sonra mantığın eklenmesini sağlar. Try-catch bloğunda yanıt beklenerek çağrılardan gelen hatalar günlüğe kaydedilebilir.
- Kesme noktası zincirindeki
İstemci kesme noktası oluşturma hakkında daha fazla bilgi için GitHub deposundaki ClientLoggerInterceptor.cs
grpc/grpc-dotnet
örneği inceleyin.
İstemci kesme noktası oluşturucularını yapılandırma
gRPC istemci kesme cihazları bir kanalda yapılandırılır.
Aşağıdaki kod:
- kullanarak
GrpcChannel.ForAddress
bir kanal oluşturur. Intercept
Kanalı kesme noktasını kullanacak şekilde yapılandırmak için uzantı yöntemini kullanır. Bu yöntemin birCallInvoker
döndürdüğünü unutmayın. Kesin türe sahip gRPC istemcileri, bir kanal gibi bir çağırıcıdan oluşturulabilir.- Çağırıcıdan bir istemci oluşturur. İstemci tarafından yapılan gRPC çağrıları, kesme noktasını otomatik olarak yürütür.
using var channel = GrpcChannel.ForAddress("https://localhost:5001");
var invoker = channel.Intercept(new ClientLoggerInterceptor());
var client = new Greeter.GreeterClient(invoker);
Uzantı Intercept
yöntemi, bir kanal için birden çok kesme noktası yapılandırmak üzere zincirlenebilir. Alternatif olarak, birden çok kesme noktası kabul eden bir Intercept
aşırı yükleme vardır. Aşağıdaki örnekte gösterildiği gibi tek bir gRPC çağrısı için herhangi bir sayıda kesme noktası yürütülebilir:
var invoker = channel
.Intercept(new ClientTokenInterceptor())
.Intercept(new ClientMonitoringInterceptor())
.Intercept(new ClientLoggerInterceptor());
Kesme makineleri zincirlenmiş Intercept
uzantı yöntemlerinin ters sırasına göre çağrılır. Önceki kodda, kesme çizgileri aşağıdaki sırayla çağrılır:
ClientLoggerInterceptor
ClientMonitoringInterceptor
ClientTokenInterceptor
gRPC istemci fabrikası ile kesme noktası yapılandırma hakkında bilgi için bkz . .NET'te gRPC istemci fabrikası tümleştirmesi.
Sunucu kesme çizgileri
gRPC sunucusu kesme makineleri gelen RPC isteklerini durdurur. Gelen isteğe, giden yanıta ve sunucu tarafı çağrısının bağlamı için erişim sağlar.
Interceptor
sunucu için geçersiz kılınacak yöntemler:
UnaryServerHandler
: Tek bir RPC'nin yolunu keser.ClientStreamingServerHandler
: İstemci akışı RPC'sini durdurur.ServerStreamingServerHandler
: Sunucu akışı RPC'sini durdurur.DuplexStreamingServerHandler
: Çift yönlü akış RPC'sini durdurur.
Sunucu gRPC kesme noktası oluşturma
Aşağıdaki kod, gelen bir bire bir RPC'yi kesen bir örnek sunar:
public class ServerLoggerInterceptor : Interceptor
{
private readonly ILogger _logger;
public ServerLoggerInterceptor(ILogger<ServerLoggerInterceptor> logger)
{
_logger = logger;
}
public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
TRequest request,
ServerCallContext context,
UnaryServerMethod<TRequest, TResponse> continuation)
{
_logger.LogInformation("Starting receiving call. Type/Method: {Type} / {Method}",
MethodType.Unary, context.Method);
try
{
return await continuation(request, context);
}
catch (Exception ex)
{
_logger.LogError(ex, $"Error thrown by {context.Method}.");
throw;
}
}
}
Geçersiz kılma UnaryServerHandler
:
- Gelen bir çağrıyı durdurur.
- Aramayla ilgili ayrıntıları günlüğe kaydeder.
- yöntemine
continuation
geçirilen parametresini çağırır. Bu, son kesme noktası ise zincirdeki sonraki kesme noktasını veya hizmet işleyicisini çağırır. - Özel durumları günlüğe kaydeder. Devamlılık beklendikten sonra hizmet yöntemi yürütüldükten sonra mantığın eklenmesine olanak tanır. Try-catch bloğunda devamı beklenerek, yöntemlerden gelen hatalar günlüğe kaydedilebilir.
hem istemci hem de sunucu kesme noktası yöntemlerinin imzası benzerdir:
continuation
, zincirdeki sonraki kesme noktasını veya hizmet işleyicisini çağıran (zincirde kesme noktası kalmadıysa) gelen RPC için bir temsilci anlamına gelir. İstemci kesme araçlarına benzer şekilde, istediğiniz zaman çağırabilirsiniz ve doğrudan devamlılık temsilcisinden yanıt döndürmenize gerek yoktur. Devamı beklenerek bir hizmet işleyicisi yürütüldükten sonra giden mantık eklenebilir.context
istek meta verileri, son tarihler ve iptal veya RPC sonucu gibi sunucu tarafı çağrısıyla ilişkili meta verileri taşır.
Sunucu kesme noktası oluşturma hakkında daha fazla bilgi için GitHub deposundaki ServerLoggerInterceptor.cs
grpc/grpc-dotnet
örneği inceleyin.
Sunucu kesme yollarını yapılandırma
gRPC sunucu kesme makineleri başlangıçta yapılandırılır. Aşağıdaki kod:
- ile
AddGrpc
uygulamaya gRPC ekler. - Hizmet seçeneğinin
ServerLoggerInterceptor
Interceptors
koleksiyonuna ekleyerek tüm hizmetler için yapılandırılır.
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc(options =>
{
options.Interceptors.Add<ServerLoggerInterceptor>();
});
}
Kesme noktası, hizmet türü kullanılarak AddServiceOptions
ve belirtilerek belirli bir hizmet için de yapılandırılabilir.
public void ConfigureServices(IServiceCollection services)
{
services
.AddGrpc()
.AddServiceOptions<GreeterService>(options =>
{
options.Interceptors.Add<ServerLoggerInterceptor>();
});
}
Kesiciler, öğesine eklenme sırasına InterceptorCollection
göre çalıştırılır. Hem genel hem de tek hizmet kesme noktası yapılandırılırsa, genel olarak yapılandırılmış kesme çizgileri tek bir hizmet için yapılandırılanlardan önce çalıştırılır.
Varsayılan olarak, gRPC sunucu kesicilerinin istek başına yaşam süresi vardır. Bu davranışı geçersiz kılma, kesme noktası türünü bağımlılık ekleme ile kaydederek mümkündür. Aşağıdaki örnek, 'yi ServerLoggerInterceptor
tek bir yaşam süresiyle kaydeder:
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc(options =>
{
options.Interceptors.Add<ServerLoggerInterceptor>();
});
services.AddSingleton<ServerLoggerInterceptor>();
}
gRPC Kesme Makineleri ile Ara Yazılım karşılaştırması
ASP.NET Core ara yazılımı , C çekirdek tabanlı gRPC uygulamalarındaki kesme makinelerine kıyasla benzer işlevler sunar. ASP.NET Core ara yazılımı ve kesme makineleri kavramsal olarak benzerdir. Her ikisi:
- gRPC isteğini işleyen bir işlem hattı oluşturmak için kullanılır.
- İşlem hattındaki bir sonraki bileşenden önce veya sonra çalışmanın gerçekleştirilmesine izin verin.
- erişimi
HttpContext
sağlayın:- Ara yazılımda
HttpContext
parametresidir. - Kesme yollarında,
HttpContext
uzantısı yöntemiyleServerCallContext.GetHttpContext
parametresi kullanılarakServerCallContext
öğesine erişilebilir. Bu özellik, ASP.NET Core'da çalışan kesişenlere özeldir.
- Ara yazılımda
gRPC Interceptor ile ASP.NET Core Ara Yazılımı arasındaki farklar:
- Interceptors:
- kullanarak gRPC soyutlama katmanı üzerinde
ServerCallContext
çalışma. - Erişim sağlayın:
- Çağrıya gönderilen seri durumdan çıkarılmış ileti.
- Çağrı seri hale getirilmeden önce döndürülen ileti.
- gRPC hizmetlerinden oluşan özel durumları yakalayabilir ve işleyebilir.
- kullanarak gRPC soyutlama katmanı üzerinde
- Ara yazılım:
- Tüm HTTP istekleri için çalışır.
- gRPC kesişimcileri öncesinde çalışır.
- Temel alınan HTTP/2 iletileri üzerinde çalışır.
- Yalnızca istek ve yanıt akışlarından baytlara erişebilir.
Ek kaynaklar
ASP.NET Core