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

AddResilienceHandler是否应置于启动代码?及日志器访问方法问询

关于HostBuilder中AddHttpClient与AddResilienceHandler的配置疑问解答

1. AddResilienceHandler是否应该放在启动代码中?

完全没必要把所有网站特定的弹性策略都堆在启动代码里,这样确实会导致代码臃肿难维护。推荐的做法是将网站特定的HttpClient配置封装到对应子项目的扩展方法中,启动代码只需要调用这些扩展方法完成注册即可。

具体实现方式:

  • 在每个子项目中创建静态扩展类,针对当前网站的需求配置HttpClient和对应的弹性策略
  • 启动代码(Program.cs)中仅通过调用这些扩展方法来注册不同的HttpClient

示例代码:

// 子项目WebsiteA中的扩展类
public static class WebsiteAHttpClientExtensions
{
    public static IServiceCollection AddWebsiteAHttpClient(this IServiceCollection services)
    {
        services.AddHttpClient("WebsiteA", client =>
        {
            client.BaseAddress = new Uri("https://website-a.com/");
            // 网站A特定的HttpClient配置
        })
        .AddResilienceHandler("websiteA-retry", (context, builder) =>
        {
            // 这里直接配置网站A专属的重试延迟逻辑
            builder.AddRetry(retryOptions =>
            {
                retryOptions.DelayGenerator = args =>
                {
                    // 网站A特定的延迟生成逻辑,比如指数退避但加上随机抖动
                    var delay = TimeSpan.FromSeconds(Math.Pow(2, args.AttemptNumber));
                    var jitter = Random.Shared.Next(0, 1000);
                    return ValueTask.FromResult(delay.Add(TimeSpan.FromMilliseconds(jitter)));
                };
            });
            // 其他网站A需要的弹性策略,比如断路器、超时等
        });

        return services;
    }
}

// 启动代码Program.cs
var builder = Host.CreateDefaultBuilder(args);
builder.Services
    .AddWebsiteAHttpClient()
    .AddWebsiteBHttpClient() // 其他子项目的扩展方法
    .AddWebsiteCHttpClient();
// ...其他启动配置

这种方式既保持了启动代码的简洁性,又让网站特定的配置逻辑归属于对应子项目,便于维护和迭代。

2. 如何在AddResilienceHandler中访问日志器?

在AddResilienceHandler的配置委托中,可以通过context.Services从依赖注入容器中解析出日志器实例,之后就能在弹性策略的逻辑中使用日志。

示例代码:

builder.Services.AddHttpClient("WebsiteB")
    .AddResilienceHandler("websiteB-retry", (context, builder) =>
    {
        // 解析对应类型的日志器
        var logger = context.Services.GetRequiredService<ILogger<WebsiteBClient>>();

        builder.AddRetry(retryOptions =>
        {
            retryOptions.DelayGenerator = args =>
            {
                logger.LogWarning("WebsiteB请求失败,正在生成第{Attempt}次重试延迟", args.AttemptNumber);
                // 网站B特定的延迟逻辑
                return ValueTask.FromResult(TimeSpan.FromSeconds(1 * args.AttemptNumber));
            };

            // 也可以在重试触发时记录日志
            retryOptions.OnRetry = args =>
            {
                logger.LogInformation("WebsiteB请求重试,当前尝试次数:{Attempt},延迟:{Delay}",
                    args.AttemptNumber, args.Delay);
                return ValueTask.CompletedTask;
            };
        });
    });

如果需要更通用的日志集成,也可以利用Polly内置的日志支持,通过AddLogging()扩展方法将策略与日志系统绑定,但上述直接解析日志器的方式更灵活,适合网站特定的日志需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 11:05:00