原文:https://www./httpclientfactory-using-polly-for-transient-fault-handling 在本系列的上一篇文章中,我介绍了使用命名和类型客户端注册的DelegatingHandlers的传出中间件的概念。尽管可以使用该方法,但ASP.NET团队希望在大多数情况下,我们无需手动构建自己的处理程序。在某些情况下,库的内置功能可能会提供我们需要的功能。例如,有时将请求包装在时序代码中以跟踪它们执行所需的时间有时会很有用。现在,它已作为默认日志记录的一部分内置到IHttpClientFactory中。在其他情况下,第三方集成可能会提供您所需的功能。例如,基于横切面的思想,在HTTP请求期间处理瞬态故障。在这种情况下,与其制作自己的重试逻辑,不如使用Polly之类的库。 <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp2.1</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.App" /> <PackageReference Include="Microsoft.Extensions.Http.Polly" Version="2.1.0" /> </ItemGroup> </Project> 应用策略 Microsoft.Extensions.Http.Polly程序包在IHttpClientBuilder上包含一个名为AddPolicyHandler的扩展方法,我们可以使用该方法添加一个处理程序,该处理程序会将使用该客户端实例的所有请求包装在Polly策略中。当我们定义一个命名或类型的客户端时,将返回IHttpClientBuilder。 services.AddHttpClient("github") .AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(10))); 在此示例中,我们定义了一个名为“ github”的客户端,并且使用了AddPolicyHandler方法来传递超时策略。您在此处提供的策略必须是IAsyncPolicy <HttpResponseMessage>。此政策将在10秒后使所有请求超时。 重用策略 在可能的情况下,使用Polly时,最好一次性的定义策略并在应用相同策略的情况下共享它们。这样,要更改策略规则,这些更改仅需要在一个地方进行。此外,它确保仅分配策略一次。当然,如果多个调用者希望通过同一断路器实例运行,则必须共享诸如断路器之类的策略。 var timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(10)); services.AddHttpClient("github") .AddPolicyHandler(timeoutPolicy); services.AddHttpClient("google") .AddPolicyHandler(timeoutPolicy); 我们将在本文后面介绍另一种策略重用的选项,使用PolicyRegistry。 瞬时故障处理 在处理HTTP请求时,我们要处理的最常见情况是瞬时错误。由于这是一个常见的要求,因此Microsoft.Extensions.Http.Polly软件包包括一个特定的扩展名,我们可以使用该扩展名快速设置处理瞬态故障的策略。 services.AddHttpClient("github") .AddTransientHttpErrorPolicy(p => p.RetryAsync(3)); 在这种情况下,当满足某些失败条件时,将重试通过客户端发出的所有请求。 AddTransientHttpErrorPolicy方法采用Func <PolicyBuilder <HttpResponseMessage>,IAsyncPolicy <HttpResponseMessage >>。这里的PolicyBuilder将被预先配置为处理HttpRequestExceptions,任何返回5xx状态码的响应以及任何带有408(请求超时)状态码的响应。这应该适合许多情况。如果您要求该策略在其他条件下应用,则需要使用其他重载来传递更具体的策略。 var retryPolicy = HttpPolicyExtensions .HandleTransientHttpError() .RetryAsync(3); var noOp = Policy.NoOpAsync().AsAsyncPolicy<HttpResponseMessage>(); services.AddHttpClient("github") .AddPolicyHandler(request => request.Method == HttpMethod.Get ? retryPolicy : noOp); 使用PolicyRegistry最后一个示例是如何通过策略注册表(policy registry)应用策略的基本演示。为了支持策略重用,Polly提供了PolicyRegistry的概念,该概念实质上是策略的容器。可以在应用程序启动时通过将策略添加到注册表中来定义。然后可以将注册表传递出去,并通过名称访问策略。 IHttpClientBuilder的扩展方法支持使用注册表(registry)将基于Polly的处理程序添加到客户端。 var registry = services.AddPolicyRegistry(); var timeout = Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(10)); var longTimeout = Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(30)); registry.Add("regular", timeout); registry.Add("long", longTimeout); services.AddHttpClient("github") .AddPolicyHandlerFromRegistry("regular"); 首先,我们必须通过DI注册一个PolicyRegistry。 Microsoft.Extensions.Http.Polly软件包包括一些扩展方法,可简化此过程。在上面的示例中,我调用了AddPolicyRegistry方法,该方法是IServiceCollection的扩展。这将创建一个新的PolicyRegistry并通过DI注册,作为IPolicyRegistry <string>和IReadOnlyPolicyRegistry <string>的实现。该方法返回策略,以便我们可以向其添加策略。 在此示例中,我们添加了两个超时策略并为其指定了名称。现在,在注册客户端时,我们可以调用IHttpClientBuilder上可用的AddPolicyHandlerFromRegistry方法,使用的是策略名称。当工厂创建命名客户端实例时,它会添加适当的处理程序,并调用“regular”重试策略。 总结作为Polly的老用户,我很高兴看到IHttpClientFactory添加了这些集成。这些库整合在一起,能够无缝处理瞬态故障,HttpClient实例非常容易启动和运行。我展示的示例非常基础和笼统,但我希望它们能为如何使用和注册策略提供一个思路。有关Polly文档和示例的更多详细信息,建议您查看Polly Wiki。在设计这种集成时,与ASP.NET和Polly团队进行的一些早期讨论非常令人高兴,因为我能够提出策略注册表扩展的有用性。 |
|