为了保障系统的稳定和安全,在调用三方服务时,可以增加重试和熔断。重试是调用一次失败后再试几试,避免下游服务一次闪断,就把整个链路终止;熔断是为了防止太多的次数的无效访问,导致系统不可知异常。

Polly是独立的重试机制的三方库,这里只说明在使用httpclient时,请求下游api时的重试和熔断。需要引入NuGet包Microsoft.Extensions.Http.Polly。

先看一个简单的重试

using Polly;var builder = WebApplication.CreateBuilder(args);builder.Services.AddHttpClient("RetryClient", httpclient =>{httpclient.BaseAddress = new Uri("http://localhost:5258");}).AddTransientHttpErrorPolicy(policyBuilder => policyBuilder.RetryAsync(3));var app = builder.Build();
//调用httpclient
app.MapGet("/test", async (IHttpClientFactory httpClientFactory) =>
{try{var httpClient = httpClientFactory.CreateClient("RetryClient");var content = await httpClient.GetStringAsync("other-api");Console.WriteLine(content);return "ok";}catch (Exception exc){if (!Count.Time.HasValue){Count.Time = DateTime.Now;}return $"{exc.Message}    【次数:{Count.I++}】  【{Count.Time.Value.ToString("yyyy-MM-dd HH:mm:ss.fffffff")}】";}
});//被调用的接口,返回状态码500
app.MapGet("/other-api", (ILogger<Program> logger) =>
{logger.LogInformation($"失败:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff")}");return Results.StatusCode(500);
});
app.Run();static class Count
{public static int I = 1;public static DateTime? Time;
}

返回的结果:

通过AddTransientHttpErrorPolicy(policyBuilder => policyBuilder.RetryAsync(3));我们让请求进行了3次重试,加上原本的一次,就是4次请求。在红色框时,会发现请求集中在极短的时间内,如果下游服务有故障,可能不会在这么短的时间内自动恢复,更好的做法是:根据重试的次数,来延长(或随机,或自建延时算法)请求的时间,比如:

.AddTransientHttpErrorPolicy(policyBuilder =>policyBuilder.WaitAndRetryAsync(3, retryNumber =>{switch (retryNumber){case 1:return TimeSpan.FromMilliseconds(500);case 2:return TimeSpan.FromMilliseconds(1000);case 3:return TimeSpan.FromMilliseconds(1500);default:return TimeSpan.FromMilliseconds(100);}}));

这时的结果如下,基本按照我们设置的时间来重试的:

还有几种重试策略,如下:

//一直重试
.AddTransientHttpErrorPolicy(policyBuilder => policyBuilder.RetryForeverAsync());
//每2秒重试一次
.AddTransientHttpErrorPolicy(policyBuilder => policyBuilder.WaitAndRetryForeverAsync(retryNumber =>
{Console.WriteLine(retryNumber);return TimeSpan.FromSeconds(2);
}));
//在5秒内4次请求,如果50%失败,就熔断10秒
.AddTransientHttpErrorPolicy(policyBuilder =>policyBuilder.AdvancedCircuitBreakerAsync(0.5d, TimeSpan.FromSeconds(5), 4, TimeSpan.FromSeconds(10)));

熔断是保护服务的手段,在本例中具体用法如下:

builder.Services.AddHttpClient("RetryClient", httpclient =>{httpclient.BaseAddress = new Uri("http://localhost:5258");}).AddTransientHttpErrorPolicy(policyBuilder =>policyBuilder.WaitAndRetryAsync(3, retryNumber =>{switch (retryNumber){case 1:return TimeSpan.FromMilliseconds(500);case 2:return TimeSpan.FromMilliseconds(1000);case 3:return TimeSpan.FromMilliseconds(1500);default:return TimeSpan.FromMilliseconds(100);}}))//熔断.AddTransientHttpErrorPolicy(policyBuilder =>policyBuilder.CircuitBreakerAsync(6, TimeSpan.FromSeconds(30)));

CircuitBreaker控制如果有6次失败的请求,就暂停30秒,具体提示如下:

.NET6之MiniAPI(二十四):用Polly重试相关推荐

  1. .NET6之MiniAPI(二十五):Dapper

    注:如果你使用Dapper一段时间了,这篇你可以跳过去了. 在第十二篇中,我们聊过官方的ORM--EntityFramework,它可以把SQL细节都隐藏,这对于一些标准化的关系数据库项目非常便捷.今 ...

  2. .NET6之MiniAPI(二十九):UnitTest

    MiniAPI的单元测试与asp.net web api的单元测试大体是相同的(毕竟都是asp.net core),只是在小细节上有一些差异,文章中会说到这点. 本文测试框架是XUnit,Mock框架 ...

  3. .NET6之MiniAPI(二十二):HttpClient

    说明:本篇不是说明HttpClient怎么使用,而以分享在asp.net core mini api框架下,HttpClient的引入和使用方式. 我们在业务开发中,免不了调用三方的服务,这时就会用到 ...

  4. .NET6之MiniAPI(二十):实体验证FluentValidation

    为了验证api post上来的数据的有效性,我们可以引入FluentValidation(详见https://fluentvalidation.net).在asp.net mvc中,使用的是模型验证, ...

  5. .NET6之MiniAPI(三十):结束篇(附链接)

    不知不觉来到了<.NET6之MiniAPI>的第三十篇,回顾之前的篇幅,主要涉及如下: HTTP请求,应答 Request 桂素伟,公众号:桂迹.NET6之MiniAPI(二):reque ...

  6. 二十四、Struts2中的UI标签

    二十四.Struts2中的UI标签 Struts2中UI标签的优势: 数据回显 页面布局和排版(Freemark),struts2提供了一些常用的排版(主题:xhtml默认 simple ajax) ...

  7. python 分数序列求和公式_Python分数序列求和,编程练习题实例二十四

    本文是关于Python分数序列求和的应用练习,适合菜鸟练习使用,python大牛绕行哦. Python练习题问题如下: 问题简述:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13 要 ...

  8. 异常处理程序和软件异常——Windows核心编程学习手札之二十四

    异常处理程序和软件异常 --Windows核心编程学习手札之二十四 CPU负责捕捉无效内存访问和用0除一个数值这种错误,并相应引发一个异常作为对错误的反应,CPU引发的异常称为硬件异常(hardwar ...

  9. 数字图像处理领域的二十四个典型算法及vc实现、第一章

    数字图像处理领域的二十四个典型算法及vc实现.第一章 作者:July   二零一一年二月二十六日. 参考:百度百科.维基百科.vc数字图像处理. --------------------------- ...

最新文章

  1. You must reset your password using ALTER USER statement before executing thi
  2. 分布式图数据库在贝壳的应用实践
  3. MyPython--进阶篇--异常
  4. Linux基础-2.目录文件的浏览、管理及维护
  5. php strlen ctf,CTF中的PHP反序列化漏洞简单分析
  6. centOS 及 ubuntu 下载地址记录
  7. 基于html5的消除类游戏,基于HTML5的消除类游戏1.doc
  8. java计算机毕业设计工会会员管理系统MyBatis+系统+LW文档+源码+调试部署
  9. SI4463实验笔记
  10. 关于电的计算机公式,电能计算-电能的计算公式-电工基础 - 电工屋
  11. uml活动图 各个功能的操作流程和分支_uml活动图
  12. 《动手学深度学习》| 2 深度学习基础
  13. 算高差改正数的计算机程序,水准测量中测量高差的改正数怎么计算?
  14. 编辑中的word变成只读_教大家word文档变成只读模式怎么改
  15. 给我“空降”一个弟兄
  16. SumaTraPDF
  17. php市场占比 2019,2019年家电市场份额占比排名
  18. Django+Vue开发生鲜电商平台之2.开发环境搭建
  19. word怎么删除空白页,Word Mac删除空白页面的图文方法
  20. 想要入行web前端要知道web前端的的基本工作职责

热门文章

  1. OCS2007R2升级LyncSrv2013 PART4:关联边缘
  2. JSP中一个页面怎么分清是链接过来还是提交过来的?
  3. AS3.0第一个实例:(Hello World)
  4. CentOS5安装Nginx1.4+PHP5.5 FastCGI
  5. Java的接口、继承与多态
  6. spring boot中servlet启动原理
  7. 算法马拉松13 A-E解题报告
  8. 如何下载EP的各个版本?
  9. CentOS升级Python2.7及安装pip
  10. 媒体层图形技术之AssetsLibrary 学习笔记