Polly:提升服务可用性

Polly是.NET生态非常著名的组件包

一 介绍

Polly 的能力

• 失败重试:当我们服务调用失败时,能够自动的重试

• 服务熔断:当我们服务部分不可用时,我们的应用可以快速响应一个熔断结果,避免持续的请求这些不可用的服务而导致整个应用程序出现问题

• 超时处理:我们为服务的请求设置一个超时时间,当超过超时时间可以按照我们预定的操作进行处理,比如返回一个缓存的结果。

• 舱壁隔离:实际上是一个限流的功能,我们可以为服务定义最大的流量和队列,这样可以避免我们的服务因为请求量过大而被压崩。

• 缓存策略:可以让我与类似于AOP方式为应用嵌入缓存的机制,当缓存命中时,我们可以快速地响应缓存,而不是持续的请求服务。

• 失败降级:当我们的服务不可用时,我们可以响应一个更友好的结果而不是报错。

• 组合策略:可以让我们将上面的 策略组合在一起,按照一定的顺序,我们可以对不同的场景组合不同的策略类,实现我们的应用程序。

Polly 使用步骤

• 定义要处理的异常类型或返回值

• 定义要处理动作(重试、熔断、降级响应等)

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

适合失败重试的场景

• 服务“失败”是短暂的,可自愈的

在失败的场景里,我们可以非常有效的避免这种网络闪断这种情况

• 服务是幂等的,重复调用不会有副作用

在失败重试情况下,有可能会造成多次调用的情况,因为有些失败,可能是你的命令已经发出了,但是你没收到响应,它会重试。

场景举例

• 网络闪断

• 部分服务节点异常

重试的过程可能就可以命中到正常的节点

最佳实践

• 设置失败重试次数

• 设置带有步长策略的失败等待间隔

• 设置降级响应

• 设置断路器

尽量设置重试的次数,尽量设置不同的间隔,否则会造成类似于DDOS的情况,当我们的重试的次数达到上限以后,我们应该为服务提供一个降级的响应,更友好的响应结果。(DDOS 全称Distributed Denial of Service,中文意思为“分布式拒绝服务”,就是利用大量合法的分布式服务器对目标发送请求,从而导致正常合法用户无法获得服务)

策略的类型

• 被动策略(异常处理、结果处理)

• 主动策略(超时处理、断路器、舱壁隔离、缓存)

组合策略

• 降级响应

• 失败重试

• 断路器

• 舱壁隔离

策略与状态共享

Policy类型状态说明
CircuitBreaker(断路器)有状态共享成功失败率,以决定是否熔断
Bulkhead(舱壁隔离)有状态共享容量使用情况,以决定是否执行动作
Cache(缓存)有状态共享缓存的对象,以决定是否命中
其它策略无状态-

有状态:时间参数、次数参数等计数实例来承载的,对不同的服务进行定义不同的策略

二  应用

我们本次使用的组件包如下:

Polly 

Polly.Extensions.Http 

Microsoft.Extensions.Http.Polly

瞬时Http错误重试策略

  错误规则

  • 网络故障(HttpRequestException)

  • HTTP 5XX 状态代码(服务器错误)

  • HTTP 408 状态代码(请求超时)

    有关配置策略的指南,请参阅有关 PolicyHttpMessageHandler 的备注。

public void ConfigureServices(IServiceCollection services)
{services.AddHttpClient("myClient", conifg =>{conifg.BaseAddress = new Uri("http://localhost:9090");}).//瞬时http错误重试策略  执行10次//抛出 HttpRequestException 或者响应码为5XX或者408AddTransientHttpErrorPolicy(p =>//错误重试配置  重试次数p.RetryAsync(10)).AddTransientHttpErrorPolicy(p =>p.WaitAndRetryAsync(10, i => TimeSpan.FromSeconds(2))).AddTransientHttpErrorPolicy(p =>//等待第i次*两秒重试 总共重试10次 越往后等的时间越久p.WaitAndRetryAsync(10, i => TimeSpan.FromSeconds(2 * i))).AddTransientHttpErrorPolicy(p =>//等待第i次*两秒重试 一直重试 直到成功p.WaitAndRetryForeverAsync(i => TimeSpan.FromSeconds(i * 3)));
}

使用自定义的Http错误重试策略

  可以根据HttpResponseMessage定义自己的重试条件

public void ConfigureServices(IServiceCollection services)
{//定义自己的策略
var reg = services.AddPolicyRegistry();//根据返回的状态码自定义自己的返回策略
reg.Add("retryforever",
Policy.HandleResult<HttpResponseMessage>(message =>
{return message.StatusCode == System.Net.HttpStatusCode.Created;}).RetryForeverAsync());//配置httpclient使用retryforever 的策略
services.AddHttpClient("myClient2").
AddPolicyHandlerFromRegistry("retryforever");//根据HttpRequestMessage 来定义策略
services.AddHttpClient("myClient3").
AddPolicyHandlerFromRegistry((registry, message) =>
{
return message.Method == HttpMethod.Get ?registry.Get<IAsyncPolicy<HttpResponseMessage>>("retryforever") :Policy.NoOpAsync<HttpResponseMessage>();});}
});}

熔断策略

public void ConfigureServices(IServiceCollection services)
{//熔断services.AddHttpClient("myClient4").AddPolicyHandler(Policy<HttpResponseMessage>.Handle<HttpRequestException>().CircuitBreakerAsync(
//报错10次后尽行熔断      handledEventsAllowedBeforeBreaking: 10,
//熔断的时间  10秒
durationOfBreak: TimeSpan.FromSeconds(10),
//当我们熔断时触发的一个事件
onBreak: (r, t) => { },//当我们熔断恢复时的事件
onReset: () => { },
//在我们恢复之前进行验证服务是否可用 
//打一部分的流量去验证我们的服务是否可用的事件
onHalfOpen: () => { }));
}

高级熔断策略

public void ConfigureServices(IServiceCollection services)
{
//高级熔断策略
services.AddHttpClient("myClient4").
AddPolicyHandler(Policy<HttpResponseMessage>.
Handle<HttpRequestException>().
AdvancedCircuitBreakerAsync(
//比例0.8服务出错进行熔断
failureThreshold: 0.8,
//10秒以内  请求出错比例0.8 进行熔断
samplingDuration: TimeSpan.FromSeconds(10),
//最小的吞吐量100 
//当我们请求量比较小的时候
//比如说我们十秒采样范围内 
//当我们的请求数超过100个时才会进行熔断 
//当请求量比较小的时候是不需要熔断
minimumThroughput: 100,
//熔断的时长  20秒
durationOfBreak: TimeSpan.FromSeconds(20),
//当我们熔断时触发的一个事件
onBreak: (r, t) => { },
//当我们熔断恢复时的事件
onReset: () => { },
//在我们恢复之前进行验证服务是否可用 
//打一部分的流量去验证我们的服务是否可用的事件
onHalfOpen: () => { }));}

服务降级策略

publicvoid ConfigureServices(IServiceCollection services)

{//定义服务降级的策略//当我们遇到熔断时 我们响应一个异常的友好结果//定义我们的熔断
var breakPolicy = Policy<HttpResponseMessage>.Handle<HttpRequestException>().AdvancedCircuitBreakerAsync(//百分之八十的服务出错进行熔断failureThreshold: 0.8,
//10秒以内  请求出错比例0.8 进行熔断
samplingDuration: TimeSpan.FromSeconds(10),
//最小的吞吐量100
//当我们请求量比较小的时候,比如说我们十秒采样范围内
//当我们的请求数超过00个时才会进行熔断
//当请求量比较小的时候是不需要熔断
minimumThroughput: 100,
//熔断的时长  20秒
durationOfBreak: TimeSpan.FromSeconds(20),
//当我们熔断时触发的一个事件
onBreak: (r, t) => { },
//当我们熔断恢复时的事件onReset: () => { },
//在我们恢复之前进行验证服务是否可用
//打一部分的流量去验证我们的服务是否可用的事件
onHalfOpen: () => { } );
//定义返回结果
var message2 = new HttpResponseMessage()
{
Content =
new StringContent("{\"IsError\":true,\"ErrorMsg\":\"服务异常\"}")
};
};//定义降级策略
var fallback = Policy<HttpResponseMessage>.Handle<BrokenCircuitException>().FallbackAsync(message2);//定义重试
var retry = Policy<HttpResponseMessage>.
Handle<Exception>().
WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(1));
//定义请求策略组合
var fallbackBreak = Policy.WrapAsync(fallback, retry, breakPolicy);
//注入HttpClient定义策略
services.AddHttpClient("myClient5").
AddPolicyHandler(fallbackBreak);
}}

限流策略

public void ConfigureServices(IServiceCollection services)
{//限流//定义请求的并发是多少var bulk = Policy.BulkheadAsync<HttpResponseMessage>(  //最大请求并发数    maxParallelization: 30,// 当我们请求超过30的并发数时// 剩下的请求怎么处理的问题// 如果我们不定义我们的队列数// 它就会抛出异常// 如果定义了队列数// 可以有20个请求在队列里排队// 只有超出队列的请求才会抛出异常// 让多出来的请求不至于直接报错maxQueuingActions: 20,//当我们的请求超出了并发数时怎么处理 这里可以定义自己的规则    onBulkheadRejectedAsync: context => Task.CompletedTask);var message3 = new HttpResponseMessage(){Content = new StringContent("{}")};//定义超出并发数策略
var fallback2 = Policy<HttpResponseMessage>.Handle<BulkheadRejectedException>().FallbackAsync(message3);//定义限流组合策略var fallbackBulk = Policy.WrapAsync(fallback2, bulk);//注入HttpClient定义策略
services.AddHttpClient("myClient6").AddPolicyHandler(fallbackBulk);}
}

 参考地址:

http://www.thepollyproject.org 

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/309681.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[汇编语言]实验一:查看CPU和内存,用机器指令和汇编指令编程。

实验一 实验任务: 查看CPU和内存&#xff0c;用机器指令和汇编指令编程。 实验内容: &#xff08;1&#xff09;实验代码: 开始执行命令: &#xff08;2&#xff09;实验代码: &#xff08;3&#xff09;实验代码: 找到了,日期为:01/01/92&#xff0c;这个是虚拟机dos环境(因…

为自己而活,这很难吗?

上周&#xff0c;我的朋友圈被 #翼装飞行失联女生死亡事件# 刷屏了&#xff0c;不知道你有没有被刷到&#xff1f;什么&#xff1f;你不知道这件事&#xff1f;没事&#xff0c;我来简单叙述一下。大致是说一个24岁女大学生翼装飞行员&#xff0c;在张家界天门山景区的一次翼装…

基于 abp vNext 和 .NET Core 开发博客项目 - 异常处理和日志记录

在开始之前&#xff0c;我们实现一个之前的遗留问题&#xff0c;这个问题是有人在GitHub Issues(https://github.com/Meowv/Blog/issues/8)上提出来的&#xff0c;就是当我们对Swagger进行分组&#xff0c;实现IDocumentFilter接口添加了文档描述信息后&#xff0c;切换分组时会…

操作系统复习题+最终版

一、单选题 1、在单处理器系统中&#xff0c;如果同时存在9个进程&#xff0c;则处于就绪队列中的进程最多有&#xff08;8&#xff09;个。 A.1 B.9 C.10 D.8 分析&#xff1a;不可能出现这样一种情况&#xff0c;单处理器系统9个进程都处于就绪状态&#xff0c;但是8个处于…

[汇编语言]实验二:字的传送

实验二 实验内容: &#xff08;1&#xff09;: &#xff08;2&#xff09;:如果把上面的ax改成al呢&#xff1f; &#xff08;3&#xff09;: &#xff08;4&#xff09;: &#xff08;1&#xff09;实验代码: &#xff08;2&#xff09;实验代码: &#xff08;3&#xf…

Web页面适配移动端方案研究

源宝导读&#xff1a;由于我们ERP目前大都是在在PC上面运行&#xff0c;大家现在关注移动端比较少&#xff0c;谈到移动端适配时&#xff0c;可能都有些生疏也可能比较好奇。以前做过一些移动端的little项目&#xff0c;那么借助这次分享的机会&#xff0c;和大家一起讨论学习下…

计网复习题和知识点+最终版

分析题&#xff1a;出处 1.以太网交换机进行转发决策时使用的 PDU 地址是 _________。 &#xff08;A &#xff09; A&#xff0e;目的物理地址 B.目的 IP 地址 C.源物理地址 D.源 IP 地址 分析&#xff1a;以太网交换机属于数据链路的设备&#xff0c;用的是MAC地址/物理地…

[汇编语言]实验三:栈和栈段

实验三 实验内容: &#xff08;1&#xff09; &#xff08;2&#xff09; &#xff08;3&#xff09; &#xff08;4&#xff09; &#xff08;5&#xff09; &#xff08;6&#xff09;

概率论+往期考试卷

工程数学2018――2019学年 一、单项选择题 1&#xff0e;对掷一颗骰子的试验&#xff0c;将“出现偶数点”称为 &#xff08; D &#xff09; A、样本空间 B、必然事件 C、不可能事件 D、随机事件 2&#xff0e;若事件A、B 互不相容&#xff0c;则下列等式中未必成立的是 &…

.net core HttpClient 使用之消息管道解析(二)

一、前言前面分享了 .net core HttpClient 使用之掉坑解析&#xff08;一&#xff09;&#xff0c;今天来分享自定义消息处理HttpMessageHandler和PrimaryHttpMessageHandler 的使用场景和区别二、源代码阅读2.1 核心消息管道模型图先贴上一张核心MessageHandler 管道模型的流程…

[汇编语言]实验五:编写,调试具有多个段的程序

&#xff08;1&#xff09; 实验代码: assume cs:code, ds:data,ss:stackdata segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h data endsstack segmentdw 0,0,0,0,0,0,0,0 stack endscode segmentstart: mov ax,stackmov ss,axmov sp,16mov ax,datamov ds,axpus…

Fibonacci Sum HDU - 6755【2020 Multi-University Training Contest 1】斐波那契数列变形+二项式定理

【杭电多校2020】Distinct Sub-palindromes 分析&#xff1a; 题目&#xff1a; The Fibonacci numbers are defined as below: Given three integers N, C and K, calculate the following summation: Since the answer can be huge, output it modulo 1000000009 (1091…

List的扩容机制,你真的明白吗?

一&#xff1a;背景1. 讲故事在前一篇大内存排查中&#xff0c;我们看到了Dictionary正在做扩容操作&#xff0c;当时这个字典的count251w&#xff0c;你把字典玩的66飞起&#xff0c;其实都是底层为你负重前行&#xff0c;比如其中的扩容机制&#xff0c;当你遇到几百万甚至千…

[汇编语言]用[bx+idata]的方式进行数组的处理-字母大小写转换

第一个字符串"BaSiC"中的小写字母变成大写字母&#xff1b; 第二个字符串"iNfOrMaTiOn"中的大写字母变成小写字母&#xff1b; 方法一: 代码如下: assume cs:codesg,ds:datasgdatasg segment db BaSiC db iNfOrMaTiOn datasg endscodesg segment start…

中科大软件测试期末复习

前言 taozs老师画的重点&#xff0c;极其重要&#xff01;&#xff01;&#xff01; 25道多选 测试是为了证明这个系统没有bug。 错 测试四象限&#xff1a; 单元测试&#xff08;工具&#xff09;、组件测试&#xff08;开发人员做&#xff0c;dao层 controller层&#xf…

.NET 程序下锐浪报表 (Grid++ Report) 的绿色发布指南

在锐浪报表官方为 CSharp 编写的开发文档&#xff1a;“在C#与VB.NET中开始使用说明.txt” 中&#xff0c;关于发布项目是这么描述的&#xff1a;★发布你的项目&#xff0c;用VS.NET制作安装程序&#xff1a;1、先创建安装项目&#xff1a;在解决方案资源管理器的根节点上点右…

C++输出对齐(如何使输出对齐)

代码如下: #include <iostream> #include <iomanip> using namespace std;int main() {cout << setw(15)<<std::left<<"unsigned int" << setw(15) << std::left<<sizeof(unsigned) << endl;cout <<…

HDFS(一)

HDFS&#xff08;一&#xff09; 参考&#xff1a; http://hadoop.apache.org/docs/r1.0.4/cn/hdfs_design.html https://www.cnblogs.com/zsql/p/11587240.html Hadoop Distribute File System&#xff1a;Hadoop分布式文件系统&#xff0c;Hadoop核心组件之一&#xff0c;作为…