Polly.Core如何根据HTTP请求URI选择对应弹性处理管道?
Polly.Core中根据请求URI动态应用弹性管道的方案
你不需要在调用PostAsync前手动检查URI并包裹执行,Polly.Core结合Polly.Extensions.Http依然支持类似旧版PolicySelector的动态管道选择逻辑,以下是两种实现方式:
方式一:在单个弹性处理中添加条件判断
直接在已有的AddResilienceHandler配置里,通过AddConditional方法指定仅对匹配目标URI的请求应用管道,其他请求自动跳过(等同于旧版的NoOp):
services.AddHttpClient(ConsentsService.ConsentsClientName, client => { client.BaseAddress = new Uri(settings.BaseUri); }) .AddResilienceHandler(Constants.PollyPipelineKey.GetConsents, (builder, context) => { var factory = context.ServiceProvider.GetRequiredService<IHttpPollyPipelineFactory>(); var pipeline = factory.CreateResiliencePipeline(); // 仅对GetConsents请求URI应用弹性管道 builder.AddConditional(pipeline, args => { var request = args.Context.GetData<HttpRequestMessage>(PollyHttpClientMessageExtensions.HttpRequestMessageKey); return request?.RequestUri?.AbsoluteUri.Contains(_consentsSettings.GetConsentsRequestUri) == true; }); });
这种方式适合只需对特定URI应用单一管道的场景,对于SetConsents这类不需要弹性策略的请求,因为不满足条件,会自动跳过管道执行,和旧版的Policy.NoOpAsync效果一致。
方式二:模拟旧版Selector模式,动态选择管道
如果需要更复杂的逻辑(比如不同URI对应不同管道),可以通过AddResilienceHandlerPolicySelector注册一个全局选择器,完全复刻旧版PolicySelector的逻辑:
services.AddHttpClient(ConsentsService.ConsentsClientName, client => { client.BaseAddress = new Uri(settings.BaseUri); }) // 注册GetConsents对应的弹性管道 .AddResilienceHandler(Constants.PollyPipelineKey.GetConsents, (builder, context) => { var factory = context.ServiceProvider.GetRequiredService<IHttpPollyPipelineFactory>(); var pipeline = factory.CreateResiliencePipeline(); builder.AddPipeline(pipeline); }) // 注册管道选择器 .AddResilienceHandlerPolicySelector((context, predicate) => { var request = context.GetData<HttpRequestMessage>(PollyHttpClientMessageExtensions.HttpRequestMessageKey); Guard.Against.Null(request); Guard.Against.Null(request.RequestUri); if (request.RequestUri.AbsoluteUri.Contains(_consentsSettings.GetConsentsRequestUri)) { // 返回对应管道的名称,触发该管道执行 return predicate(Constants.PollyPipelineKey.GetConsents); } if (request.RequestUri.AbsoluteUri.Contains(_consentsSettings.SetConsentsRequestUri)) { // 返回null表示不应用任何管道,等同于NoOp return null; } throw new InvalidOperationException("Polly policy for consents not found"); });
注意事项
- 确保已安装
Polly.Extensions.Http包,Polly.Core本身不包含与HttpClient的集成逻辑,该包提供了相关扩展方法。 - 使用
PollyHttpClientMessageExtensions.HttpRequestMessageKey可以从Polly的上下文(Context)中获取当前的HttpRequestMessage,进而拿到请求URI。 - 两种方式都无需手动在请求调用处处理管道逻辑,HttpClient会自动根据选择规则为每个请求匹配对应的弹性策略。
内容的提问来源于stack exchange,提问作者pampua84
相关产品推荐
相关产品推荐

