前言

简单整理一下polly 重试。

正文

在开发程序中一般都有一个重试帮助类,那么polly同样有这个功能。

polly 组件包:

polly 功能包

polly.Extensions.Http 专门针对http的扩展包

Miscrosoft.Extension.Http.Polly 看到这个名字,那么99%是针对官方.net core的扩展包,是HttpClientFactory 的扩展。

polly有下面一些功能:

  1. 失败重试

  2. 服务熔断

  3. 超时处理

  4. 舱壁处理

  5. 缓存策略

  6. 失败降级

  7. 组合策略

其他都好理解,但是舱壁处理 是什么呢?

这个是限流功能,服务定义最大的流量和队列,避免请求量过大而崩溃。

组合策略,就是对上面的功能可以自由组合。

polly 使用步骤:

  1. 定于要处理的异常类型和返回值

  2. 定义要处理的工作

  3. 使用定义的策略来执行代码

polly的源代码:

https://github.com/App-vNext/Polly

polly 针对http的扩展包:

https://github.com/App-vNext/Polly.Extensions.Http

适合polly 重试的场景:

1.服务"失败"是短暂的,可自愈的。

针对这种http请求,无状态的是非常适用的。

2.服务是"幂等"的,重复调用不会产生副作用

这个幂等可以简单为多次执行,并不会影响到最初达到的效果。

比如说个人查询,查询多次的话,效果是相同的。具体幂等可以百度一下,不过觉的看下https://baike.baidu.com/item/%E5%B9%82%E7%AD%89/8600688?fr=aladdin就够了,因为有些人讲的神乎其神。

具体场景:

  1. 服务闪断

  2. 部分节点不可用

在使用重试过程中,最好达到下面几个要求:

  1. 设置失败次数

  2. 设置有步长策略的失败等待间隔

  3. 设置降级响应

  4. 设置断路器

前面说过polly 是针对httpClientFactory 的扩展,那么其融合性其实是非常好的。

比如说,grpc当监听到AddTransientHttpErrorPolicy错误的时候,那么可以启动对应的策略进行重试,RetryAsync就是polly的扩展,里面设置重试次数20次。

services.AddGrpcClient<Helloworld.Greeter.GreeterClient>(options =>
{
options.Address = new Uri("https://localhost:5001");
}).ConfigurePrimaryHttpMessageHandler(provider =>
{
var handle = new SocketsHttpHandler();
handle.SslOptions.RemoteCertificateValidationCallback = (a, b, c, d) => true;
return handle;
}).AddTransientHttpErrorPolicy(p=>p.RetryAsync(20));

看下AddTransientHttpErrorPolicy,其实个人感觉RetryAsync倒是没有必要去看,看AddTransientHttpErrorPolicy 是为了知道啥时候会触发这个重试,以及知道如何去定义我们自己的Policy。

AddTransientHttpErrorPolicy:

public static IHttpClientBuilder AddTransientHttpErrorPolicy(
this IHttpClientBuilder builder,
Func<PolicyBuilder<HttpResponseMessage>, IAsyncPolicy<HttpResponseMessage>> configurePolicy)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
} if (configurePolicy == null)
{
throw new ArgumentNullException(nameof(configurePolicy));
} var policyBuilder = HttpPolicyExtensions.HandleTransientHttpError(); // Important - cache policy instances so that they are singletons per handler.
var policy = configurePolicy(policyBuilder); builder.AddHttpMessageHandler(() => new PolicyHttpMessageHandler(policy));
return builder;
}

从名字中可以看到HandleTransientHttpError就是处理异常的。

public static PolicyBuilder<HttpResponseMessage> HandleTransientHttpError()
{
return Policy<HttpResponseMessage>.Handle<HttpRequestException>().OrTransientHttpStatusCode();
}

这里表示HttpRequestException 会触发,或者OrTransientHttpStatusCode一些状态码下会触发,看下OrTransientHttpStatusCode。

OrTransientHttpStatusCode:

public static PolicyBuilder<HttpResponseMessage> OrTransientHttpStatusCode(
this PolicyBuilder<HttpResponseMessage> policyBuilder)
{
if (policyBuilder == null)
throw new ArgumentNullException(nameof (policyBuilder));
return policyBuilder.OrResult(HttpPolicyExtensions.TransientHttpStatusCodePredicate);
}

查看HttpPolicyExtensions.TransientHttpStatusCodePredicate:

 private static readonly Func<HttpResponseMessage, bool> TransientHttpStatusCodePredicate = (Func<HttpResponseMessage, bool>) (response => response.StatusCode >= HttpStatusCode.InternalServerError || response.StatusCode == HttpStatusCode.RequestTimeout);

这里面表示 HttpStatusCode.InternalServerError(500)和 HttpStatusCode.RequestTimeout(408) 会进行重试。

同样可以设置间隔时间进行重试:

services.AddGrpcClient<Helloworld.Greeter.GreeterClient>(options =>
{
options.Address = new Uri("https://localhost:5001");
}).ConfigurePrimaryHttpMessageHandler(provider =>
{
var handle = new SocketsHttpHandler();
handle.SslOptions.RemoteCertificateValidationCallback = (a, b, c, d) => true;
return handle;
}).AddTransientHttpErrorPolicy(p=>p.WaitAndRetryAsync(20,i=>TimeSpan.FromSeconds(2)));

还可以使用WaitAndRetryForever 表示一直重试,直到成功,看需求。

同样也可以自定义一些状态或者一些情况,做一些事情:

var reg = services.AddPolicyRegistry();

reg.Add("retryforever", Policy.HandleResult<HttpResponseMessage>(message =>
{
return message.StatusCode == System.Net.HttpStatusCode.Created;
}).RetryForever()); services.AddHttpClient("GreeterClient").AddPolicyHandlerFromRegistry("retryforever");

上面表示针对GreeterClient客户端,增加一些retryforever的处理策略。

后面会介绍这种策略架子是如何实现的,在细节篇。

那通过Polic就可以针对不同场景,进行定义不同的策略,做出一些相应。看项目需求,这里就不多介绍了,每个项目都不一样。

下一节polly熔断。

重新整理 .net core 实践篇————polly失败重试[三十四]的更多相关文章

  1. 重新整理 .net core 实践篇—————3种配置验证[十四]

    前言 简单整理一些配置的验证. 正文 配置的验证大概分为3类: 直接注册验证函数 实现IValidteOptions 使用Microsoft.Extensions.Options.DataAnnota ...

  2. 重新整理 .net core 实践篇————依赖注入应用之援军[四]

    前言 介绍第三方依赖注入框架Autofac,看看为我们解决什么问题. 下面介绍4个点: 命名注册 属性注册 aop 注入 子容器命名 正文 为什么我们需要使用第三方框架?第三方框架为我们做了什么?第三 ...

  3. 重新整理 .net core 实践篇—————服务与配置之间[十一二]

    前言 前面基本介绍了,官方对于asp .net core 设计配置和设计服务的框架的一些思路.看下服务和配置之间是如何联系的吧. 正文 服务: public interface ISelfServic ...

  4. 重新整理 .net core 实践篇——— 权限中间件源码阅读[四十六]

    前言 前面介绍了认证中间件,下面看一下授权中间件. 正文 app.UseAuthorization(); 授权中间件是这个,前面我们提及到认证中间件并不会让整个中间件停止. 认证中间件就两个作用,我们 ...

  5. 重新整理 .net core 实践篇—————日志系统之战地记者[十五]

    前言 本节开始整理日志相关的东西.先整理一下日志的基本原理. 正文 首先介绍一下包: Microsoft.Extengsion.Logging.Abstrations 这个是接口包. Microsof ...

  6. 重新整理 .net core 实践篇—————工作单元模式[二十六]

    前言 简单整理一下工作单元模式. 正文 工作单元模式有3个特性,也算是其功能: 使用同一上下文 跟踪实体的状态 保障事务一致性 工作单元模式 主要关注事务,所以重点在事务上. 在共享层的基础建设类库中 ...

  7. 重新整理 .net core 实践篇————配置应用[一]

    前言 本来想整理到<<重新整理.net core 计1400篇>>里面去,但是后来一想,整理 .net core 实践篇 是偏于实践,故而分开. 因为是重新整理,那么就从配置开 ...

  8. 重新整理 .net core 实践篇————熔断与限流[三十五]

    前言 简单整理一下熔断与限流,跟上一节息息相关. 正文 polly 的策略类型分为两类: 被动策略(异常处理.结果处理) 主动策略(超时处理.断路器.舱壁隔离.缓存) 熔断和限流通过下面主动策略来实现 ...

  9. 重新整理 .net core 实践篇————依赖注入应用[二]

    前言 这里介绍一下.net core的依赖注入框架,其中其代码原理在我的另一个整理<<重新整理 1400篇>>中已经写了,故而专门整理应用这一块. 以下只是个人整理,如有问题, ...

随机推荐

  1. 实施CRM系统后 企业客户服务的改变

    通过实施CRM客户管理系统,企业的竞争力和盈利能力得到大幅提高.在这个过程中,客户服务不仅能够持续的满足客户的需求,还能够促进客户与企业建立长期的互惠互利的良好客户关系,这也为企业赢得了更多的商机和利 ...

  2. opencv——轮廓发现与轮廓(二值图像)分析

    引言 二值图像分析最常见的一个主要方式就是轮廓发现与轮廓分析,其中轮廓发现的目的是为轮廓分析做准备,经过轮廓分析我们可以得到轮廓各种有用的属性信息. 这里顺带提下边缘检测,和轮廓提取的区别: 边缘检测 ...

  3. Iterable 和 Iterator

    可以被for循环输出的为iterable (可迭代对象) 可以被next()调用并不断返回下一个数据的对象为iterator迭代器(python一切皆对象) 数据流,无法知晓其终点,只能推过next不 ...

  4. 5分钟让你理解K8S必备架构概念,以及网络模型(下)

    写在前面 在这用XMind画了一张导图记录Redis的学习笔记和一些面试解析(源文件对部分节点有详细备注和参考资料,欢迎关注我的公众号:阿风的架构笔记 后台发送[导图]拿下载链接, 已经完善更新): ...

  5. Linux_部署日志服务器

    一.部署日志服务 1.查看自己的系统是否安装(一般默认安装) [root@localhost ~]# rpm -qa | grep rsyslog rsyslog-8.37.0-13.el8.x86_ ...

  6. 企业案例-Mysql误删除用户表如何恢复

    1.不小心删除了mysql所有用户 mysql> delete from mysql.user where 1=1; Query OK, 5 rows affected (0.00 sec) # ...

  7. JavaSE 知识图谱

    JAVA基础语法 DOS命令 JAVA介绍 JDK安装 JAVA环境的搭建 关键字 注释 标识符命名规则(编码规范) 字面值常量 进制转换 基本类型 变量(局部变量.静态变量) 运算符 表达式 控制语 ...

  8. 8.10-11 mount、umount

    8.10 mount:挂载文件系统 mount命令可以将指定的文件系统挂载到指定目录(挂载点),在Linux系统下必须先挂载所有的设备,然后才能被访问,挂载其实就是为要访问的设置开个门(开门才能访问) ...

  9. Centos 7常见问题——SMBus Host Controller not enabled!

    在使用虚拟机Centos7操作系统偶尔会遇到,重启开机过程中出现如下图情况,无法正常开机 出现这种情况的可能原因就是你在虚拟机中添加了网卡或硬盘,还有给内存添加了容量之类就会导致开机有这种报错 解决方 ...

  10. 使用vue-i18n实现中英文切换(内含动态属性的绑定)

    最近做学生管理系统,因为有国外的学生,所以要进行中英文切换,查了查Vue中使用vue-i18n插件能够实现网页的中英文切换,学习内容如下: 一.下载vue-i18n插件 npm install vue ...