作者: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的时候,得到了正常的返回结果

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

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

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

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

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

这里对于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"

案例七 服务质量

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的状态码

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

总结

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

Ocelot(五)- 流量限制、服务质量相关推荐

  1. 服务质量QoS(Quality of Service)的基础知识

    QoS概述 浅谈QoS--QoS概述 网络抓包工具Wireshark下载安装&使用详细教程 QoS简介 在传统的计算机网络中,网络设备对于数据包的处理方式都是相同的,平等的对待所有的数据流量. ...

  2. 如何构建一个流量无损的在线应用架构 | 专题中篇

    简介:本篇是整个<如何流量无损的在线应用架构>系列的第二篇,这一系列共三篇,旨在使用最为朴素的语言将影响在线应用流量稳定性的技术问题做一个归类,这些问题的解决方案有的只是一些代码层面的细节 ...

  3. excel打开2个独立窗口_10个提高黑五网一独立站营销邮件打开率,点击率和转化率的策略...

    最近在找一些关于Q4以及黑五网一邮件营销的一些新的想法,Google翻到了Common Thread Collective的一篇文章:<Black Friday Email Marketing: ...

  4. 网络互连基础——笔记

    导致LAN拥塞的常见原因: 广播域或冲突域中的主机太多 广播风暴. 组播数据流太多 带宽太低 使用集线器拓展网络 ARP广播太多 注:路由器提供WAN连接,使用串行接口建立WAN连接,在思科路由器上, ...

  5. ArchSummit微课堂|蘑菇街DevOps实践及心路历程分享

    本文整理自 #ArchSummit微课堂#--赵成分享的蘑菇街DevOps实践及心路历程,主要介绍一些运维体系建设中的的经历和实践, 什么是DevOps?为什么是DevOps? 蘑菇街DevOps实践 ...

  6. ITU-T Technical Paper: QoS的构建模块与机制

    本文翻译自ITU-T的Technical Paper:<How to increase QoS/QoE of IP-based platform(s) to regionally agreed ...

  7. 【计算机网络】《计算机网络(第5版 )》1~5章笔记

    计算机网络(第5版 ) Andrew S. Tanenbaum / David J. Wetherall 括号内为页码 文章目录 第1章 引言 传输模式(13) 互联处理器分类(14) 网络体系结构( ...

  8. 交换式路由器与路由式交换机

    现在路由器和交换机之间的区别也越来越模糊,多层路由器与交换机都可以同时实现交换和路由的功能,它们之间还有不同吗?各自特点何在?如何更好地根据应用需求进行选择?     一.传统的交换机和路由器 普通交 ...

  9. CCNA 知识点归纳(持续更新中)

    此文为本人在CCNA学习过程中自我总结归纳的知识点 若有不足或错误之处欢迎指正. 文章目录 一.网络互联 1.1 网络互联基础 1.2 OSI参考模型 二.以太网和数据封装 2.1 以太网布线 2.2 ...

最新文章

  1. SAP WM LRFMD中Variant参数的影响初探
  2. 社群分享:涨粉的35个玩法和技巧
  3. good-Windows下搭建PHP开发环境(Apache+PHP+MySQL)
  4. n阶行列式计算----c语言实现(完结)
  5. python `__format__`
  6. 4款idea主题,非常的炫酷
  7. 更改Android 默认键盘映射值
  8. html自动弹出公告代码,可定时自动关闭的弹出层广告窗口代码
  9. BPF类型格式BTF
  10. vue3.0中使用百度离线地图
  11. python教你如何把自己的微信变成机器人
  12. 数据科学猫:数据分析的主要类型、描述性分析、预测性分析与规范性分析
  13. ThinkPad E420/E520 Win10 开机慢的问题
  14. 生成淘宝短链tb.cn
  15. 干货教程:数据结构与算法之美
  16. html时显示当前时间的时钟,javascript实现页面的实时时钟显示示例
  17. 最新C语言深入剖析班项目实战教程(国嵌 唐老师主讲)
  18. 平方根法 乔累斯基分解Cholesky_解线性方程组的直接解法
  19. 浏览器缓存机制之Cookie
  20. 人工智能第二次作业 书上69页作业

热门文章

  1. 在Teams app代码中enable nullable
  2. 书评:Just the Computer Essentials(Vista)
  3. 如何使计算机为您读取文档
  4. 给Web开发人员的以太坊入坑指南
  5. 算法复杂度分析(下)
  6. gitlab永久设置密码
  7. Druid源码分析系列1:dataSource.init()的准备工作
  8. Linux常用C函数-接口处理篇(网络通信函数)
  9. 简洁强大的JavaWeb框架Blade
  10. 浅谈SQL注入风险 - 一个Login拿下Server(转)