提问人:Yago Oliveira 提问时间:8/23/2023 最后编辑:Yago Oliveira 更新时间:8/24/2023 访问量:92
确定订阅的哪个 GRPC 服务已关闭 .NET 7
Identify which GRPC service subscribed is down .NET 7
问:
我有这个用于订阅 GRPC 流服务的实现,但是,我必须确定其中一个服务何时关闭并调用事件以通知 UI。
public async Task Subscribe()
{
await Policy
.Handle<RpcException>(e => e.Status.StatusCode == StatusCode.Unavailable)
.WaitAndRetryAsync(
10,
attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)),
onRetry: (e, ts) => {
logger.Warning("Subscription connection lost. Trying to reconnect in {Seconds}s!", ts.Seconds);
})
.ExecuteAsync(() => {
IAsyncEnumerable<Notification> stream = await subscribe.Subscribe(currentUser)
await foreach (Notification? ev in stream)
{
switch (reply.ActionCase)
{
case Notification.ActionOneofCase.Service1:
logger.Warning("Incoming reply 'Service1'");
break;
case Notification.ActionOneofCase.Service2:
//TODO:
break;
}
}
});
}
我尝试使用polly,但我不知道如何在一个特定服务关闭时获取。我需要确定其中一个服务何时关闭以通知 UI。识别哪个服务关闭的最佳方法是什么?
编辑:
这就是每个服务的注入方式:
private static void AddGrpcService<T>(IServiceCollection services,
Config config) where T : class
{
SocketsHttpHandler socketsHandler = new SocketsHttpHandler()
{
PooledConnectionIdleTimeout = Timeout.InfiniteTimeSpan,
KeepAlivePingDelay = TimeSpan.FromSeconds(60),
KeepAlivePingTimeout = TimeSpan.FromSeconds(30),
EnableMultipleHttp2Connections = true
};
MethodConfig 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 }
}
};
ServiceConfig serviceConfig = new() { MethodConfigs = { defaultMethodConfig } };
services.AddGrpcClient<T>(o => {
o.Address = new Uri(config.GrpcUrl);
})
.ConfigureChannel(o => {
o.Credentials = GetGrpcClientCredentials(config);
o.ServiceConfig = serviceConfig;
})
.ConfigurePrimaryHttpMessageHandler(() => socketsHandler);
}
答:
1赞
Peter Csala
8/23/2023
#1
在确定下游服务是否已关闭时遇到问题?
在 和 Polly 集成的情况下,有一个称为 HandleTransientHttpError
的静态方法。每当状态代码为 408 或 5xx 时,就会触发此操作。这也会在 .HttpClient
HttpRequestException
请记住,它不会触发 429(请求过多)等状态代码,这也可能表明下游服务已过载。
最初,我会建议拍摄一些类似的状态代码。但是由于我不熟悉 GRPC,所以我最好根据文档和这个特使问题在这里猜测。
readonly StatusCode[] RetriableStatusCodes = new[]
{
StatusCode.Cancelled,
StatusCode.DeadlineExceeded,
StatusCode.ResourceExhausted
};
...
await Policy
.Handle<RpcException>(e => RetriableStatusCodes.Contains(e.Status.StatusCode))
...
您想知道应该在何处以及如何触发通知吗?
或可能是触发通知的最佳位置。onRetry
onRetryAsync
如果策略将触发并在睡眠之前调用这些用户委托。
换句话说,如果初始尝试失败并且谓词被计算为 ,那么它将调用委托。委托完成后,它将在第一次重试尝试之前进入睡眠状态。Handle
true
onRetry(Async)
不会被调用onRetry(Async)
- 如果谓词的计算结果为
Handle
false
- 如果超过最大重试次数,则无论
Handle
评论