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. SuperMap流数据应用技术方案

    流数据应用技术方案针对流数据应用场景,针对流数据的海量.多源.持续等特征,进行持续地获取相关的动态位置,以及持续地分析.处理和挖掘. 本章沿用基于单机SuperMap iServer环境,介绍流数据处 ...

  2. 第27天:安全开发-PHP应用&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞 - Shortcut

    https://www.kancloud.cn/manual/thinkphp5_1/354000 ThinkPHP-Vuln-master

  3. Windows系统无法打开‘’网络发现‘’功能

    Windows10无法开启网络发现 解决办法: 1. services.msc 2. 开启 SSDP Discovery ,设置 启动类型为 自动 ,服务状态为 启动 Windows7 无法开启网络发 ...

  4. 采集数据产品描述有超链接///设置免运费后,达到免送标准,其他运费不显示///给产品详情页面的图片点击放大是个模态窗///在shop页面有重复的产品展示,去重

    //产品描述有超链接,去掉 function remove_product_hyperlinks($content) { if (is_product()) { // 确保只在产品页面上应用 $con ...

  5. JSP+Java编程资源

    <JSP+Servlet+Tomcat应用开发从零开始学(第2版)>源码课件视频下载地址: https://pan.baidu.com/s/1HkFRul3wYBxe-skXCoQPwg ...

  6. uprobe

    本章的我们来学习uprobe ,顾名思义,相对于内核函数/地址的监控,主要用于用户态函数/地址的监控.听起来是不是有点神奇,内核怎么监控用户态函数的调用呢?本章的内容包括: 如何使用uprobe 内核 ...

  7. 4.3 等比数列及其前n项和

    \(\mathbf{{\large {\color{Red} {欢迎到学科网下载资料学习}} } }\)[[高分突破系列] 高二数学下学期同步知识点剖析精品讲义! \(\mathbf{{\large ...

  8. js中判断数据类型的方法有哪些

    判断数据类型可以使用 typeof 但是typeof 判断数组和函数时返回的都是Object 不能具体判断,这时使用 instanceof 可以判断对象是否是另一个函数创造的 : 用法: typeof ...

  9. 我们在 vue 项目中如何做路由导航守卫

    一般在 src 文件夹新建一个 permission 文件 ,单独用来做路由导航守卫业务 ,在 main.js 导入文件即可 : 主要功能有 判断是否有 token ,以此判断用户是不是登录了 :

  10. 现在 Llama 具备视觉能力并可以在你的设备上运行 - 欢迎使用 Llama 3.2

    Llama 3.2 来了!今天,我们欢迎 Llama 系列的下一个版本加入 Hugging Face.这次,我们很高兴与 Meta 合作发布多模态和小型模型.在 Hub 上提供了十个开源模型 (5 个 ...