在Polly v8的OnOpened回调中识别触发熔断的HttpClient
解决方案
1. 修改策略工厂,接收客户端名称参数
让策略工厂的创建方法支持传入HttpClient的名称,确保每个客户端的熔断策略能关联到自身标识:
public ResiliencePipeline<HttpResponseMessage> Create(string clientName) { var builder = new ResiliencePipelineBuilder<HttpResponseMessage>() .AddTimeout(MapToTimeoutStrategyOptions()) // 将客户端名称传入熔断策略配置 .AddCircuitBreaker(MapToHttpCircuitBreakerStrategyOptions(clientName)) .AddRetry(MapToServiceNowHttpRetryStrategyOptions()); // 补上缺失的Build()调用,返回构建好的策略管道 return builder.Build(); }
2. 在DI配置中传递HttpClient名称
利用AddResilienceHandler提供的上下文(AddResilienceHandlerContext),直接获取当前HttpClient的名称并传给策略工厂:
services .AddHttpClient("ClientA") .AddResilienceHandler("ClientA", (builder, context) => { var strategyFactory = context.ServiceProvider.GetRequiredService<IResiliencyStrategyFactory>(); // context.ServiceName就是当前HttpClient的命名("ClientA") builder.AddPipeline(strategyFactory.Create(context.ServiceName)); }); services .AddHttpClient("ClientB") .AddResilienceHandler("ClientB", (builder, context) => { var strategyFactory = context.ServiceProvider.GetRequiredService<IResiliencyStrategyFactory>(); builder.AddPipeline(strategyFactory.Create(context.ServiceName)); });
3. 调整熔断策略配置,关联客户端名称
修改熔断策略的配置方法,接收客户端名称参数,在回调中直接使用该标识反馈故障:
private HttpCircuitBreakerStrategyOptions MapToHttpCircuitBreakerStrategyOptions(string clientName) => new() { MinimumThroughput = resiliencyConfig.CircuitBreakerConfig.Throughput, FailureRatio = resiliencyConfig.CircuitBreakerConfig.FailureRatio, SamplingDuration = TimeSpan.FromSeconds(resiliencyConfig.CircuitBreakerConfig.SamplingDuration), BreakDuration = TimeSpan.FromSeconds(resiliencyConfig.CircuitBreakerConfig.DurationOfBreakSeconds), OnClosed = args => { // 反馈指定客户端已恢复 Console.WriteLine($"客户端 {clientName} 熔断状态已关闭,服务恢复正常"); return Task.CompletedTask; }, OnOpened = args => { // 反馈指定客户端触发熔断 Console.WriteLine($"客户端 {clientName} 已触发熔断,服务暂时不可用"); return Task.CompletedTask; } };
(可选)通过OperationKey传递标识
如果你想通过OnCircuitOpenedArguments的OperationKey属性获取客户端名称,可以在DI配置的策略构建阶段,给ResilienceContext设置默认的OperationKey:
services .AddHttpClient("ClientA") .AddResilienceHandler("ClientA", (builder, context) => { var strategyFactory = context.ServiceProvider.GetRequiredService<IResiliencyStrategyFactory>(); builder.AddPipeline(strategyFactory.Create()) // 设置默认OperationKey为当前HttpClient名称 .Configure(resilienceContext => resilienceContext.OperationKey = context.ServiceName); });
此时在熔断回调中就可以通过args.Context.OperationKey获取客户端名称:
OnOpened = args => { string clientName = args.Context.OperationKey; Console.WriteLine($"客户端 {clientName} 已触发熔断"); return Task.CompletedTask; }
内容的提问来源于stack exchange,提问作者Lane Goolsby
相关产品推荐
相关产品推荐

