Ocelot(五)- 流量限制、服务质量

作者:markjiang7m2
原文地址:https://www.cnblogs.com/markjiang7m2/p/10965300.html
源码地址:https://gitee.com/Sevenm2/OcelotDemo

本文是我关于Ocelot系列文章的第五篇,流量限制、服务质量。Ocelot允许针对具体的服务接口进行流量限制,以便下游服务不会过载而影响响应速度。服务质量则是Ocelot根据下游服务响应的结果做出判断,当超过一定次数的响应失败时,Ocelot认为该服务不可用,自动产生熔断,在一定的时间范围内不再向该服务转发请求,同时Ocelot也支持自定义的请求超时时间,当下游响应超过设定的时间,会认为该服务响应失败。

关于更多的Ocelot功能介绍,可以查看我的系列文章

  • Ocelot - .Net Core开源网关

  • Ocelot(二)- 请求聚合与负载均衡

  • Ocelot(三)- 服务发现

  • Ocelot(四)- 认证与授权

本文中涉及案例的完整代码都可以从我的代码仓库进行下载。

  • 仓库地址:https://gitee.com/Sevenm2/OcelotDemo

案例六 流量限制

Ocelot支持流量限制,只要在路由中添加 RateLimitOptions配置即可

"RateLimitOptions": {	"ClientWhiteList": [	"markadmin"	],	"EnableRateLimiting": true,	"Period": "1m",	"PeriodTimespan": 30,	"Limit": 5	
}


  • ClientWhiteList:数组,在请求头中包含ClientId=xxx的请求不受限流控制,其中ClientId这个key可以修改,xxx表示配置的白名单。

  • EnableRateLimiting:是否启用限流

  • Period:限流控制的时间周期,输入单位支持s(秒), m(分), h(时), d(天)

  • PeriodTimespan:恢复等待时间,当访问超过限流限制的次数后,需要等待的时间,单位为s,如当一分钟内访问超过5次,就需要等待30秒后,访问才会重新有效

  • Limit:一个时间周期内允许访问的最大次数。

下面来看案例,在 ReRoutes中添加一组路由

  1. {

  2. "DownstreamPathTemplate": "/api/ocelot/{postId}",

  3. "DownstreamScheme": "http",

  4. "DownstreamHostAndPorts": [

  5. {

  6. "Host": "localhost",

  7. "Port": 8001

  8. }

  9. ],

  10. "UpstreamPathTemplate": "/ocelot/ratelimit/{postId}",

  11. "UpstreamHttpMethod": [ "Get" ],

  12. "Priority": 2,

  13. "RateLimitOptions": {

  14. "ClientWhiteList": [

  15. "markadmin"

  16. ],

  17. "EnableRateLimiting": true,

  18. "Period": "1m",

  19. "PeriodTimespan": 30,

  20. "Limit": 5

  21. }

  22. }

在这里我只是添加多了一组路由,但下游服务接口是重用了之前使用过的接口,流量限制部分配置上面已经介绍过了。下面运行来看结果。

当我第一次访问 http://localhost:4727/ocelot/ratelimit/5的时候,得到了正常的返回结果

640?wx_fmt=png

而且,在请求头可以看到流量限制的相关信息

640?wx_fmt=png

然后,我又很快地继续发出请求,可以看到,当我第六次发出请求的时候,得到了 429ToManyRequests的状态

640?wx_fmt=png

而此时的请求头信息也会不一样,这里可以看到 Retry-After28,意思是在28秒后可以恢复请求

640?wx_fmt=png

这证明,我们的Ocelot网关流量限制的作用起效了,而且与我们的配置一致。
在等待30秒之后,我重新发出请求,又得到了正常的返回结果

640?wx_fmt=png

当我在请求头中加上 [ClientId]=markadmin后,清空Postman的请求记录,重新开始发出请求,无论请求多少次,Ocelot也不会对我的访问进行限流

640?wx_fmt=png

这里对于PeriodTimespan(恢复等待时间)的算法,我倒是有点疑问的。我一开始的理解是,基于上面案例的配置,当一分钟内访问超过5次时,就需要等待 Period + PeriodTimespan,也就是从第一个有效请求开始算起,一分半钟之后Ocelot才会重新正常转发请求,但是我做了几次重复实验,得到的结果都是:当一分钟内访问到第1次时,Ocelot开始进入 PeriodTimespan时间内的倒计时,也就是实际的重置时间为 PeriodTimespan

为了更加明确地验证这个问题,我使用 OcelotConsole项目进行测试。
首先,修改路由配置如下:

  1. {

  2. "DownstreamPathTemplate": "/api/ocelot/{postId}",

  3. "DownstreamScheme": "http",

  4. "DownstreamHostAndPorts": [

  5. {

  6. "Host": "localhost",

  7. "Port": 8001

  8. }

  9. ],

  10. "UpstreamPathTemplate": "/ocelot/ratelimit/{postId}",

  11. "UpstreamHttpMethod": [ "Get" ],

  12. "Priority": 2,

  13. "RateLimitOptions": {

  14. "ClientWhiteList": [

  15. "markadmin"

  16. ],

  17. "EnableRateLimiting": true,

  18. "Period": "1m",

  19. "PeriodTimespan": 10,

  20. "Limit": 5

  21. }

  22. }

然后,在 OcelotConsole项目中添加代码如下:

  1. public static async Task Main(string[] args)

  2. {

  3. using (var client = new HttpClient())

  4. {

  5. for (var i = 0; i < 100; i++)

  6. {

  7. Console.WriteLine(DateTime.Now);


  8. var result = await client.GetAsync("http://localhost:4727/ocelot/ratelimit/5");

  9. Console.WriteLine($"{result.StatusCode}, {result.Content.ReadAsStringAsync().Result}");

  10. System.Threading.Thread.Sleep(1000);

  11. }

  12. Console.Read();

  13. }

  14. }

每隔1s就发出一次请求,运行,在命令窗口得到以下输出:

  1. 2019/6/3 13:33:31

  2. OK, This is from localhost:8001, path: /api/ocelot/5

  3. 2019/6/3 13:33:32

  4. OK, This is from localhost:8001, path: /api/ocelot/5

  5. 2019/6/3 13:33:33

  6. OK, This is from localhost:8001, path: /api/ocelot/5

  7. 2019/6/3 13:33:34

  8. OK, This is from localhost:8001, path: /api/ocelot/5

  9. 2019/6/3 13:33:35

  10. OK, This is from localhost:8001, path: /api/ocelot/5

  11. 2019/6/3 13:33:36

  12. TooManyRequests, API calls quota exceeded! maximum admitted 5 per 1m.

  13. 2019/6/3 13:33:37

  14. TooManyRequests, API calls quota exceeded! maximum admitted 5 per 1m.

  15. 2019/6/3 13:33:38

  16. TooManyRequests, API calls quota exceeded! maximum admitted 5 per 1m.

  17. 2019/6/3 13:33:39

  18. TooManyRequests, API calls quota exceeded! maximum admitted 5 per 1m.

  19. 2019/6/3 13:33:40

  20. TooManyRequests, API calls quota exceeded! maximum admitted 5 per 1m.

  21. 2019/6/3 13:33:41

  22. OK, This is from localhost:8001, path: /api/ocelot/5

  23. 2019/6/3 13:33:43

  24. OK, This is from localhost:8001, path: /api/ocelot/5

  25. 2019/6/3 13:33:44

  26. OK, This is from localhost:8001, path: /api/ocelot/5

  27. 2019/6/3 13:33:45

  28. OK, This is from localhost:8001, path: /api/ocelot/5

  29. 2019/6/3 13:33:46

  30. OK, This is from localhost:8001, path: /api/ocelot/5

  31. 2019/6/3 13:33:47

  32. TooManyRequests, API calls quota exceeded! maximum admitted 5 per 1m.

  33. 2019/6/3 13:33:48

  34. TooManyRequests, API calls quota exceeded! maximum admitted 5 per 1m.

  35. 2019/6/3 13:33:49

  36. TooManyRequests, API calls quota exceeded! maximum admitted 5 per 1m.

  37. 2019/6/3 13:33:50

  38. TooManyRequests, API calls quota exceeded! maximum admitted 5 per 1m.

  39. 2019/6/3 13:33:51

  40. TooManyRequests, API calls quota exceeded! maximum admitted 5 per 1m.

然后,我又通过修改参数,得出如下结果:

  • PeriodTimespan=10, Limit=5:5个成功,5个失败

  • PeriodTimespan=10, Limit=6:6个成功,4个失败

  • PeriodTimespan=20, Limit=5:5个成功,15个失败

  • PeriodTimespan=30, Limit=5:5个成功,25个失败

似乎都是与我前面得到的结论相同,与官方文档不一致。
我在GitHub上提了一个issue:https://github.com/ThreeMammals/Ocelot/issues/910,期待能得到答复。

流量限制的全局配置

  1. "RateLimitOptions": {

  2. "DisableRateLimitHeaders": true,

  3. "QuotaExceededMessage": "Customize Tips!",

  4. "HttpStatusCode": 999,

  5. "ClientIdHeader": "Test"

  6. }

  • DisableRateLimitHeaders:当设为true时,请求头中就不会输出流量限制的相关信息,默认值:"false"

  • QuotaExceededMessage:当请求数量超出流量限制时,输出的信息,默认值:"API calls quota exceeded! maximum admitted {Limit} per {Period}."

  • HttpStatusCode:当请求数量超出流量限制时,输出的状态码,默认值:"429"

  • ClientIdHeader:标识为白名单中的客户端的请求头key,默认值:"ClientId"


640?wx_fmt=png

640?wx_fmt=png

案例七 服务质量

Ocelot支持服务质量与熔断,意味着当下游服务不可用时,Ocelot会进行自动熔断,不再将请求转发给该下游服务。来看看配置

  1. "QoSOptions": {

  2. "ExceptionsAllowedBeforeBreaking":3,

  3. "DurationOfBreak":3000,

  4. "TimeoutValue":5000

  5. }

  • ExceptionsAllowedBeforeBreaking:允许异常次数,当Ocelot转发给该下游服务连续出现异常次数达到该数字时,Ocelot会进行自动熔断,一段时间内不再向该下游服务转发请求

  • DurationOfBreak:熔断时间,单位为ms(毫秒),持续多长时间不向该下游服务转发请求

  • TimeoutValue:服务质量配置项,超时时间,单位为ms(毫秒),当Ocelot向下游服务转发请求多长时间后,自动认为该请求超时

ExceptionsAllowedBeforeBreaking 必须跟 DurationOfBreak一起使用,TimeoutValue可以单独使用。

首先需要安装 Polly支持程序,通过Nuget搜索 Ocelot.Provider.Polly或者通过以下命令安装

  1. Install-Package Ocelot.Provider.Polly

然后在Startup.cs中的 ConfigureServices方法注册该中间件

  1. using Ocelot.Provider.Polly;

  1. public void ConfigureServices(IServiceCollection services)

  2. {

  3. ……

  4. services.AddOcelot()

  5. .AddPolly();

  6. ……

  7. }

ReRoutes中添加一组路由

  1. {

  2. "DownstreamPathTemplate": "/api/ocelot/{postId}",

  3. "DownstreamScheme": "http",

  4. "DownstreamHostAndPorts": [

  5. {

  6. "Host": "localhost",

  7. "Port": 8001

  8. }

  9. ],

  10. "UpstreamPathTemplate": "/ocelot/qos/{postId}",

  11. "UpstreamHttpMethod": [ "Get" ],

  12. "Priority": 2,

  13. "QoSOptions": {

  14. "ExceptionsAllowedBeforeBreaking": 3,

  15. "DurationOfBreak": 3000,

  16. "TimeoutValue": 5000

  17. }

  18. }

为了看出熔断效果,我将 8001端口的下游服务停止了,然后运行OcelotDemo项目

当第一次向网关发出请求时,得到 500的状态码

640?wx_fmt=png

连续3次请求过后,就会得到 503的状态码,证明Ocelot已经产生熔断

640?wx_fmt=png

总结

在这篇文章中就跟大家介绍了Ocelot的两个基础功能,在路由中进行配置即可使用,不需要依赖于第三方的服务。当然在我实践的过程中产生的一个疑问暂时还没得到答案,如果有知道原因的朋友也可以给我留言,感激不尽。
结合前面的几篇文章,大家在设计项目API网关的时候就可以综合地考虑到底哪些功能应该配置使用,如何适当地建立路由表。另外,我在这几个案例中为了突出要介绍的功能,基本上都是一组路由单独配置一个功能,而在实际项目中通常都是需要在一组路由当中同时配置多个功能的,希望大家在实际项目中能够灵活运用。今天就先跟大家介绍到这里,希望大家能持续关注我们。

640?wx_fmt=jpeg

640?wx_fmt=jpeg


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

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

相关文章

java中静态修饰符(static)的使用

static-静态 修饰属性 静态属性,也称为静态变量 类变量等 static 数据类型 属性名; 使用 静态内容独立存放在方法区 静态内容在内存中只有一份,被该类所有对象共享 普通属性所有对象在对象内容中都有一份 可以通过类名.静态属性名的方式直接访问静态属性 静态属性封装之…

Ocelot(三)- 服务发现

作者&#xff1a;markjiang7m2原文地址&#xff1a;https://www.cnblogs.com/markjiang7m2/p/10907856.html源码地址&#xff1a;https://gitee.com/Sevenm2/OcelotDemo本文是我关于Ocelot系列文章的第三篇&#xff0c;主要是给大家介绍Ocelot的另一功能。与其说是给大家介绍&a…

P3527 [POI2011]MET-Meteors 整体二分 + 树状数组

洛谷 题意&#xff1a; 思路&#xff1a; 考虑整体二分前&#xff0c;一定要思考一下直接二分怎么做。显然对每个城市&#xff0c;当<pos<pos<pos的时候收集不够足够的陨石&#xff0c;>pos>pos>pos的时候能收集足够多陨石&#xff0c;这个时候pospospos即…

Ocelot(二)- 请求聚合与负载均衡

作者&#xff1a;markjiang7m2原文地址&#xff1a;https://www.cnblogs.com/markjiang7m2/p/10865511.html源码地址&#xff1a;https://gitee.com/Sevenm2/OcelotDemo在上一篇Ocelot的文章中&#xff0c;我已经给大家介绍了何为Ocelot以及如何简单使用它的路由功能&#xff0…

「分布式系统理论」系列专题

如今互联网已经成为整个社会的基础设施&#xff0c;分布式系统并不是少数大公司的专属&#xff0c;所以分布式系统理论可能是你迟早需要掌握的知识。如果你是程序员&#xff0c;相信这些文章你肯定能看懂&#xff1b;如果你不是程序员&#xff0c;相信这些能使你能更懂程序员&a…

SQL Server 2012如何打开2016的profiler文件

作者&#xff1a;markjiang7m2原文地址&#xff1a;https://www.cnblogs.com/markjiang7m2/p/10980191.html背景在上星期&#xff0c;公司负责support的同事接到反馈说某个项目生产环境上的某个页面加载很慢&#xff0c;一般遇到这种问题&#xff0c;我们的support同事都会先上…

Codeforces Round #655 (Div. 2) E. Omkar and Last Floor 区间dp + 巧妙的状态设计

传送门 题意&#xff1a; 思路&#xff1a; 按照贪心的思路来考虑的话&#xff0c;显然是每一列111的个数越多越好&#xff0c;所以我们能放到一列就放到一列。设f[l][r]f[l][r]f[l][r]为在[l,r][l,r][l,r]内&#xff0c;区间全部都在里面的贡献。显然这个贡献就是全部落在[l…

AKS使用Azure File实现动态持久化存储

本文作者|搪瓷小娃娃本文来源|搪瓷小娃娃博客园如我们所知&#xff0c;Kubernetes通过 Volume 为集群中的容器提供存储&#xff0c;通过Persistent Volume 和 Persistent Volume Claim实现Volume 的静态供给和动态供给。Azure File和Azure Disk 也在Kubernetes 支持的动态供给 …

ASP.NET Core 应用程序状态

在ASP.NET Core中&#xff0c;由多种途径可以对应用程序状态进行管理&#xff0c;使用哪种途径&#xff0c;由检索状态的时机和方式决定。应用程序状态指的是用于描述当前状况的任意数据。包括全局和用户特有的数据。开发人员可以根据不同的因素来选择不同的方式存储状态数据&a…

Asp.net core使用MediatR进程内发布/订阅

1、背景最近&#xff0c;一个工作了一个月的同事离职了&#xff0c;所做的东西怼了过来。一看代码&#xff0c;惨不忍睹&#xff0c;一个方法六七百行&#xff0c;啥也不说了吧&#xff0c;实在没法儿说。介绍下业务场景吧&#xff0c;一个公共操作A&#xff0c;业务中各个地方…

[开源] FreeSql.Tools Razor 生成器

FreeSql 经过半年的开发和坚持维护&#xff0c;在 0.6.x 版本中完成了几大重要事件&#xff1a;1、按小包拆分&#xff0c;每个数据库实现为单独 dll&#xff1b;2、实现 .net framework 4.5 支持&#xff1b;3、同时支持 MySql.Data、MySqlConnector 的实现&#xff1b;4、自定…

WebAssembly和Blazor:解决了一个存在十年的老问题

本文要点WebAssembly 是一种新的客户端技术&#xff0c;可以在所有现代浏览器&#xff08;包括移动浏览器&#xff09;中实现近乎原生的性能&#xff0c;而且不需要插件。许多语言&#xff0c;包括 C、C#、Go 和 Rust&#xff0c;都可以编译成面向基于栈的 WebAssembly 虚拟机的…

《电商后台系统产品逻辑解析》学习笔记

文是我阅读《电商产品经理宝典&#xff1a;电商后台系统产品逻辑全解析》一书的学习笔记&#xff0c;为后续我司做家居电商后台系统储备相关领域的业务知识。一、支撑线后台概览“前端用户的一小步&#xff0c;后台系统的一大步”&#xff0c;平时常见的功能如购物车、优惠券等…

P3403 跳楼机 同余最短路

传送门 题意&#xff1a; 思路&#xff1a; 转换一下题目就是用若干x,y,zx,y,zx,y,z能凑出来多少个<h<h<h的数。先考虑两个数y,zy,zy,z的情况&#xff0c;我们如果能求出来这两个数能凑出来的数设为sumsumsum&#xff0c;让后sumkx<hsumkx<hsumkx<h求出来…

NopCommerce 4.2的安装与运行

、关于NopCommerceNopCommerce是国外ASP.Net领域一个高质量的B2C开源电商项目&#xff0c;最新版本4.2基于ASP.NET Core MVC 2.2和EF Core 2.2开发&#xff0c;其强大的功能特性和插件机制使其成为了.NET领域开源电商项目的标杆。当然&#xff0c;还有一些其他的开源电商项目如…

P1527 [国家集训队]矩阵乘法 整体二分 + 二维树状数组

传送门 题意&#xff1a; 思路&#xff1a; 算是个整体二分的板子啦&#xff0c;不过这个是二维的矩阵&#xff0c;我们只需要把一位树状数组改成二维的&#xff0c;让后动态维护单点加&#xff0c;区间查询前缀和即可。 //#pragma GCC optimize(2) #include<cstdio>…

应用性能问题解决实际案例

某项目在上线前的APT&#xff08;Application Performance Testing应用程序性能测试&#xff09;过程中发现性能问题&#xff0c;性能测试结果影响是否上线&#xff0c;紧急求助外部项目组技术专家。因分属不同项目&#xff0c;只能通过项目组提供的信息进行分析。第一轮评审现…

Worker Service in ASP .NET Core

介绍提到 ASP.NET Core&#xff0c;我们多半会想到 ASP.NET MVC、ASP.NET Web API、Razor page 及 Blazor。随着 .NET Core 3.0 的推出&#xff0c;今天会介绍一个全新推出的功能&#xff1a;Work Service 。我们可以在 Visual Studio 2019 中通过预定的项目模版快速创建一个 W…

ASP.NET Core 奇淫技巧之动态WebApi

一.前言接触到动态WebApi&#xff08;Dynamic Web API&#xff09;这个词的已有几年&#xff0c;是从ABP框架里面接触到的&#xff0c;当时便对ABP的这个技术很好奇&#xff0c;后面分析了一波&#xff0c;也尝试过从ABP剥离一个出来作为独立组件来使用&#xff0c;可是后来因与…

Codeforces Round #693 (Div. 3) E. Correct Placement 思维

传送门 题意&#xff1a; 思路&#xff1a; 对于每个人都有个二元组(x,y)(x,y)(x,y)&#xff0c;从题意中提取有效信息就是&#xff1a;当(x1,y1)(x_1,y_1)(x1​,y1​)的最大值大于(x2,y2)(x_2,y_2)(x2​,y2​)的最大值&#xff0c;(x1,y1)(x_1,y_1)(x1​,y1​)的最小值大于(…