.Net?Core微服务网关Ocelot超时、熔断、限流
(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun)
基本概念
超时、熔断、限流听起来好像很远,但实际上用在方方面面。很多人可能还搞不懂熔断是做什么,其实可以把熔断理解为一种防护措施。做个假设,在微服务体系下,某个下游服务响应很慢,然后随着时间推移,会有越来越多的请求堆积,从而会导致各种严重后果,单说连接池大量被占用就很要命。更不用说服务之间还要相互调用,你等我10秒,我等你5秒,不仅毫无体验感,高可用也就成了空谈。不如换个思路:与其等10秒返回一个请求失败,不如马上就返回请求失败。这样一来,请求堆不起来,资源也有时间释放或者恢复。这个动作就叫熔断,或者叫短路。有点像家用电路,一旦有漏电直接跳闸,最大程度保障安全。
熔断的概念基本有了,接下来给网关集成。这里需要用到一个叫polly的库。
简单说下它:polly由.net实现,是一个非常优秀的库,主要提供重试、熔断、超时、恢复等功能,当然今天主角不是它,想研究的可以去官方看下:https://github.com/App-vNext/Polly
接下来开始集成。首先添加nuget包:
然后注册相关服务:
public void ConfigureServices(IServiceCollection services) { services.AddOcelot() .AddPolly() .AddConsul() .AddConfigStoredInConsul(); }
接下来在配置文件添加节点:
"QoSOptions": { "ExceptionsAllowedBeforeBreaking":3, "DurationOfBreak":10000, "TimeoutValue":5000 }
- ExceptionsAllowedBeforeBreaking:阈值,当转发到下游的服务连续出现的异常次数达到阈值就会触发熔断。必须和DurationOfBreak一起设置。
- DurationOfBreak:熔断持续时间,单位毫秒。必须和ExceptionsAllowedBeforeBreaking一起设置。
- TimeoutValue:限定时间内未响应的请求直接超时,单位毫秒。可以单独设置
- tips:ocelot默认超时时间是90秒,90秒啊
然后写一个方法,休眠10秒:
[HttpGet] public IActionResult TimeOut() { System.Threading.Thread.Sleep(10000); return Ok(); }
超时
准备工作做完了,现在调用timeout方法:
方法是休眠10秒,但是等待5秒左右就主动返回了503,说明超时的设置已经生效。
熔断
当转发到下游某个服务的请求连续出现超时情况时,网关就会判断是否达到阈值,如果是就触发熔断,在此期间的请求统一返回503,熔断时间过了以后恢复正常。按上面配置来看:连续超时3次会触发熔断,熔断持续10秒。我们仍然调用Timeout方法,连续3次以后:
没有触发熔断时,只能等过5秒自动超时,很显然现在已经触发了超时,所以在200毫秒就直接返回了结果。熔断期间访问别的方法也会是503:
和开头写的一样,熔断和电路短路跳闸是思路是一样的,就算家里N条线只有1条漏电,那还是会跳闸整个屋子不能用电,这种做法最大程度上保证了程序安全。
限流
假设现在只能承载1万并发,那么过来5万并发会怎么样?一般情况下,只要持续时间稍久一些,服务基本全都挂了。这种情况在生产环境难免会发生,毕竟业务量也无法测算那么精准。所以为了提高可用性,瞬时请求超过最大阈值,其他的全都忽略才能保证服务安全可用。让客户等下一次请求,总好过服务挂了没的请求。
限流也是配置就能实现,在路由中新增下面的节点:
"RateLimitOptions": { "ClientWhitelist": [], "EnableRateLimiting": true, "Period": "1s", "PeriodTimespan": 1, "Limit": 1 }
- ClientWhitelist:客户端白名单,白名单不受限流规则限制。
- EnableRateLimiting:是否启用限流。
- Period:周期,单位有s(秒)、m(分)、h(时)、d(天),比如1h
- PeriodTimespan:多少秒后重试。
- Limit:周期内允许多少个请求。
想要更精细的控制,还可以在Global部分添加这些:
"RateLimitOptions": { "DisableRateLimitHeaders": false, "QuotaExceededMessage": "Customize Tips!", "HttpStatusCode": 999, "ClientIdHeader" : "Test" }
- DisableRateLimitHeaders:是否禁用X-Rate-Limit、Retry-After标头。
- QuotaExceededMessage:触发限流时返回的消息。
- HttpStatusCode:触发限流时返回的http状态码(一般会写429)。
- ClientIdHeader:用来识别客户端的标头。
- tips:DisableRateLimitHeaders中提到的X-Rate-Limit、Retry-After:X-Rate-Limit——标准时间内允许多少个请求,Retry-After——触发限流以后多久可以重试。
接下来修改我的配置:
"RateLimitOptions": { "ClientWhitelist": [ "myclient" ], "EnableRateLimiting": true, "Period": "1s", "PeriodTimespan": 10, "Limit": 1 }
修改全局配置:
"RateLimitOptions": { "DisableRateLimitHeaders": false, "QuotaExceededMessage": "123123", "HttpStatusCode": 429, "ClientIdHeader": "Test" }
按配置来看,我设置1秒内最多允许1个请求,超过就触发限流。之后的请求都会返回429和123123,持续10秒。来试试:
等待10秒后再次请求,恢复正常:
白名单
白名单里的客户端是不会受到限流限制的。按照配置添加请求头,就可以被白名单识别:
请求时添加这个请求头,无论怎么刷都不会被限流。
超时、熔断、限流的必要性和好处是不言而喻的,但是上生产一定要注意配置的合理性,充分综合业务场景和需要才是王道,毕竟技术如果不解决问题那就毫无意义。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员之家。
相关文章
在ASP.NET 2.0中操作数据之十三:在DetailsView控件中使用TemplateField
就像在GridView中那样,DetailsView控件也可以同样的使用TemplateField。本文用两个TemplateField来演示在它的使用方法。2016-05-05NopCommerce架构分析之(四)基于路由实现灵活的插件机制
本文主要介绍NopCommerce中,通过注册路由,实现插件的机制,同时,NopCommerce中每个插件都集成IPlugin接口,插件拥有安装和卸载的功能。2016-04-04在ASP.NET 2.0中操作数据之十七:研究插入、更新和删除的关联事件
本文主要讲解ASP.NET 2.0中如何在点击插入、更新、删除等按钮时关联和触发事件,以便我们在事件中写代码,实现我们期望的效果。2016-05-05在ASP.NET 2.0中操作数据之十四:使用FormView 的模板
前面介绍了GridView和DetailsView控件可以使用TemplateField来自定义输出,但是呈现的样式还是一种四四方方的格子状。当我们想完全自定义的时候,他们就爱莫能助了,这时我们就可以使用FormView控件来实现我们想要的效果了。2016-05-05在ASP.NET 2.0中操作数据之四十六:使用SqlDataSource控件检索数据
在前面的教程里,我们用ObjectDataSource控件充分的将表现层和数据访问层(DAL)分开来。在这篇教程里我们看看怎样在一个表现层和数据访问层区分的不是很严格的简单程序中使用SqlDataSource控件。2016-05-05解读ASP.NET 5 & MVC6系列教程(17):MVC中的其他新特性
这篇文章主要介绍了ASP.NET 5中全局导入、获取IP相关信息、文件上传等其他新特性,需要的朋友可以参考下2016-06-06解读ASP.NET 5 & MVC6系列教程(4):核心技术与环境配置
这篇文章主要介绍了ASP.NET 5 核心技术与环境配置,需要的朋友可以参考下2016-06-06解读ASP.NET 5 & MVC6系列教程(13):TagHelper
这篇文章主要介绍了新版MVC6中强大的TagHelper功能,需要的朋友可以参考下2016-06-06NopCommerce架构分析之(三)EntityFramework数据库初试化及数据操作
本文介绍IStartupTask,该类会在系统启动时执行,IStartupTask调用IEfDataProvider进行数据库的初始化。2016-04-04
最新评论