HttpClientFacotry Part 4: 集成 Polly 处理瞬时失效

原文地址:https://www.stevejgordon.co.uk/httpclientfactory-using-polly-for-transient-fault-handling

在使用 Polly 之前,我们需要添加包引用到项目中,Microsoft.Extensions.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 的扩展方法称为 AddPolicyHander() ,我们可以使用它增加处理器到 Polly 策略中。IHttpClientBuilder 在定名命名的客户端的时候被返回。

可以在 ConfigureServices() 方法中使用该扩展。

services.AddHttpClient("github")
.AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(10)));

在本示例中,我们定义了一个名为 github 的客户端,然后使用 AddPolicyHandler() 方法提供了超时策略。这里提供的策略必须是 IAsyncPolicy<HttpResponseMessage> 类型。该策略对于每个请求在 10s 之后超时。

重用策略

在使用 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 包提供了一个专用的扩展,我们可以用来快速设置处理瞬时失效的策略。

例如,当瞬时失效发生的时候,对命名的 HttpClient 添加对请求的重试,我们可以如下注册重试策略:

services.AddHttpClient("github")
.AddTransientHttpErrorPolicy(p => p.RetryAsync(3));

在此示例中,所有通过该客户端发出的请求,当失效条件满足的时候将会被重试。AddTransientHttpErrorPolicy() 方法提供 Func<PolicyBuilder<HttpResponseMessage>, IAsyncPolicy<HttpResponseMessage>>。PolicyBuilder 将用来预配置处理 HttpRequestExceptions,任何返回 5xx 状态码和 408 状态码 (请求超时) 的响应。这适合多种状态,如果你需要策略应用到其它条件,你可以使用其它的重载提供更专用的策略。

但是注意,在执行重试的时候,需要考虑等幂问题,重试 GET 请求很安全,如果我们发出请求,然后没有收到任何响应,我们可以安全地没有任何危险地重试。但是,考虑一下我们重试一个 HTTP POST 请求,此时,我们必须更加小心,因为原来的请求可能已经被接收到,但是我们在接收响应的时候失败了。此时,重试会导致重复的数据,或者破坏在下游系统中存储的数据。此时,你需要更多的关于下游系统在收到相同的请求一次以上时如何处理的知识。重试还是安全的吗?当你拥有下游服务的时候,比较容易处理该问题,你可能,例如,使用某个唯一标识符来防止重复 POST。

当你无法控制下游系统,或者你知道重复的 POST 可能带来随后的负面影响,你将需要更加小心地控制策略。一个可能适合的方式是定义不同的命名/强类型的客户端,为有副作用的创建一个,为没有副作用的创建另外一个。然后,针对所采取的操作使用正确的客户端。然而,这可能变得有点难以管理。另一个更好的方式是使用 AddPolicyHandler 的重载。它使得我们可以访问 HttpRequestMessage,所以策略可以有条件地应用。该重载看起来如下所示:

AddPolicyHandler(Func<HttpRequestMessage, IAsyncPolicy<HttpResponseMessage>> policySelector)

我们将注意到 policySelector 委托可以访问 HttpRequestMessage,并且期待返回 IAsyncPolicy<HttpResponseMessage>。我们不需要访问 PolicyBuilder 的设置如前例所示来出来瞬时失败,如果我们希望处理通常的瞬时失效错误,我们需要为策略定义期望处理的条件。为了更加简便,Polly 项目包含了一个助手扩展,我们可以借助它设置好 PolicyBuilder 来处理通常的瞬时失效错误。为了使用该扩展方法,我们需要添加 Polly.Extensions.Http 包。

我们可以调用 HttpPolicyExtensions.HandleTranisentHttpError() 来获得一个 PolicyBuilder 对象,它被使用瞬时失效条件进行配置。我们可以使用 PolicyBuilder 来创建一个适当的重试策略,它可以在 Http Get 请求的时候,有条件地被应用,在该示例中,任何其它的请求方法将使用 NoOp 策略。

var retryPolicy = HttpPolicyExtensions
.HandleTransientHttpError()
.RetryAsync(3); var noOp = Policy.NoOpAsync().AsAsyncPolicy<HttpResponseMessage>(); services.AddHttpClient("github")
.AddPolicyHandler(request => request.Method == HttpMethod.Get ? retryPolicy : noOp);

使用策略注册表

最后一个示例,将演示如何通过一个策略注册表来应用策略。为了支持策略的重用,Polly 提供了 PolicyRegisty 的概念,它就是一个策略的容器。它可以在应用程序设置的时候添加策略到注册表中。该注册表然后可以各处使用,并通过名字来访问其中的策略。

在 IHttpClientBuilder 上的扩展方法也支持使用注册表为客户端基于处理器添加策略。

首先,我们必须在 DI 容器中添加一个 PolicyRegistry 的注册。Microsoft.Extensions.Http.Polly 包中包含了一些简化使用的扩展方法。在上面的示例中,我调用的 AddPolicyRegistry() 方法是 IServiceCollection 的一个扩展方法。它将创建一个新的 PolicyRegistry 并以接口 IPolicyRegistry<string> 和 IReadOnlyPolicyRegistry<string> 的实现注册到 DI 容器中。该方法返回策略,可以通过它添加策略到其中。

在下面的示例中,我们添加了两个超时策略并命名。然后,在注册客户端的时候,我们可以调用 AddPolicyHandlerFromREgistry() 方法,它在 IHttpClientBuilder 上。它使用我们希望使用的策略名称。当工厂创建该命名的客户端的时候,它将称为 "regular" 的重试策略添加适当的处理器。

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

总结

随着长时间使用 Polly,我非常高兴地看到它被集成到 IHttpClientFactory 中。这些库合起来使得很容易设置并一起使用,HttpClient 实例可以流畅地处理瞬时失效。我们展示的示例很基本和通用。但是,我希望它们可以提供策略是如何使用和注册的思路。更多的 Polly 文档和示例,我建议你查阅 Polly 的 Wiki 页面。

Part 1 – HttpClientFactory in ASP.NET Core 2.1 Part 1 介绍

Part 2 – HttpClientFactory in ASP.NET Core 2.1 Part 2:定义命名和类型化的客户端

Part 3 – HttpClientFactory in ASP.NET Core 2.1 Part 3: 对处理器使用对外请求中间件

Part 4 – HttpClientFacotry Part 4: 集成 Polly 处理瞬时失效

Part 5 – HttpClientFactory in ASP.NET Core 2.1 Part 5: 日志

HttpClientFacotry Part 4: 集成 Polly 处理瞬时失效的更多相关文章

  1. ASP.Net Core2.1中的HttpClientFactory系列二:集成Polly处理瞬态故障

    前言:最近,同事在工作中遇到了使用HttpClient,有些请求超时的问题,辅导员让我下去调研一下,HttpClinet的使用方式已经改成了之前博客中提到的方式,问题的原因我已经找到了,就是因为使用了 ...

  2. ASP.NET Core 2.1 中的 HttpClientFactory (Part 4) 整合Polly实现瞬时故障处理

    原文:https://www.stevejgordon.co.uk/httpclientfactory-using-polly-for-transient-fault-handling发表于:2018 ...

  3. spring集成shiro,事务失效问题 not eligible for auto-proxying

    BeanPostProcessor bean实例化顺序有关,@Configuration会最先实例化,也就是在spring启动完成之前. 导致Configuration中使用的注入,没能在spring ...

  4. NetCore项目实战篇07---服务保护之polly

    1.  为什么要用polly 前面的项目中,一个服务调用另一个(Zhengwei.Identity调用Zhengwei.Use.Api)服务时是直接调用的,在这个调用的过程中可能会发生各种瞬态故障,这 ...

  5. oracle asm 概念

    automated storage management ,即自动存储管理,简称asm .. 在oracle 10g 这个版本之前,管理一个大型数据库成千上万的数据文件对数据库管理员来说是一个既无技术 ...

  6. MTBF

    MTBF,即平均故障间隔时间,英文全称是"Mean Time Between Failure".是衡量一个产品(尤其是电器产品)的可靠性指标.单位为"小时".它 ...

  7. HttpClient在.NET Core中的正确打开方式

    问题来源 长期以来,.NET开发者都通过下面的方式发送http请求: using (var httpClient = new HttpClient()) { var response = await ...

  8. asp.net core microservices 架构之eureka服务发现

    一 简介 微服务将需多的功能拆分为许多的轻量级的子应用,这些子应用相互调度.好处就是轻量级,完全符合了敏捷开发的精神.我们知道ut(单元测试),不仅仅提高我们的程序的健壮性,而且可以强制将类和方法的设 ...

  9. 手动造轮子——基于.NetCore的RPC框架DotNetCoreRpc

    前言     一直以来对内部服务间使用RPC的方式调用都比较赞同,因为内部间没有这么多限制,最简单明了的方式就是最合适的方式.个人比较喜欢类似Dubbo的那种使用方式,把接口层单独出来,作为服务的契约 ...

  10. 网关Ocelot功能演示安排的明明白白~~~

    前言 网关(Gateway)在微服务架构中至关重要,可以将其理解为是外部客户端(前端.MVC后台等调用方)与后台服务的连接点,通过这层可以做统一的处理,比如路由.身份认证和授权.服务治理等: 网关的好 ...

随机推荐

  1. Windows安装winget

    打开GitHub链接地址:https://github.com/microsoft/winget-cli/releases 选择最新版本,点进去后 找到名为后缀名为 ".msixbundle ...

  2. LeetCode 1388. Pizza With 3n Slices(3n 块披萨)(DP)

    给你一个披萨,它由 3n 块不同大小的部分组成,现在你和你的朋友们需要按照如下规则来分披萨: 你挑选 任意 一块披萨.Alice 将会挑选你所选择的披萨逆时针方向的下一块披萨.Bob 将会挑选你所选择 ...

  3. Win10 LTSC 从 2019(1809) 升级到 2021(21H2) 后找回丢失的 WSL

    Win 10 LTST 2019 升级 2021 很简单,直接挂载 ISO 镜像以后,运行 setup.exe,剩下的就是耐心等待了. 升级完成后,用户信息和安装的软件基本上都在,VM15 启动的时候 ...

  4. 进程管理中的active_mm是做什么的?

    在Linux内核中,进程管理涉及到许多复杂的数据结构和机制,其中active_mm是与内存管理相关的一个关键概念.理解active_mm需要先了解与之相关的一些基本内核结构和概念. 基本概念 mm_s ...

  5. 【01】DataFrame的创建和属性

    DataFrame是一个表格型的数据结构,可以看成就是excel中的表格. 官方文档:https://pandas.pydata.org/docs/reference/frame.html DataF ...

  6. npm install报错 Error: EACCES: permission denied

    报错内容 Unable to save binary /root/packageadmin/spring-boot-admin-2.1.6/spring-boot-admin-server-ui/no ...

  7. 小集训 CSP-S 模拟赛

    DAY 1 A.喜剧的迷人之处在于 小思维题不必细讲 B. 镜中的野兽 状压+容斥 $ gcd (x) + lcm(x) = m $ ,可以得知 $ gcd(x) $ 一定是 m 的因子,那么就可以枚 ...

  8. FluxCD 多集群应用的设计与实现

    前言 FluxCD 是 CNCF 的孵化项目,可以让我们以 GitOps 的方式轻松地交付应用.和另一个同类的 CNCF 孵化项目 ArgoCD 不同,FluxCD 是许多 toolkit 的集合,天 ...

  9. C/C++ volatile restrict 用法

    volatile和restrict是C和C++中的两个关键字,都用于指示编译器优化. volatile volatile的本意是"易变的",用法和const一样: volatile ...

  10. 轻量级网络-RepVGG 论文解读

    背景知识 VGG 和 ResNet 回顾 MAC 计算 卷积运算与矩阵乘积 点积 ACNet 理解 ACBlock 的 Pytorch 代码实现 摘要 RepVGG 模型定义 RepVGG Block ...