You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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");
});

注意事项

  1. 确保已安装Polly.Extensions.Http包,Polly.Core本身不包含与HttpClient的集成逻辑,该包提供了相关扩展方法。
  2. 使用PollyHttpClientMessageExtensions.HttpRequestMessageKey可以从Polly的上下文(Context)中获取当前的HttpRequestMessage,进而拿到请求URI。
  3. 两种方式都无需手动在请求调用处处理管道逻辑,HttpClient会自动根据选择规则为每个请求匹配对应的弹性策略。

内容的提问来源于stack exchange,提问作者pampua84

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 21:53:11