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

本文是我关于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中添加一组路由

{ "DownstreamPathTemplate": "/api/ocelot/{postId}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 8001 } ], "UpstreamPathTemplate": "/ocelot/ratelimit/{postId}", "UpstreamHttpMethod": [ "Get" ], "Priority": 2, "RateLimitOptions": { "ClientWhiteList": [ "markadmin" ], "EnableRateLimiting": true, "Period": "1m", "PeriodTimespan": 30, "Limit": 5 } }

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

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

Ocelot_043_ratelimit_request1

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

Ocelot_047_ratelimit_request1header

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

Ocelot_044_ratelimit_request6

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

Ocelot_048_ratelimit_request6header

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

Ocelot_045_ratelimit_request7

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

Ocelot_046_ratelimit_nolimit

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

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

{ "DownstreamPathTemplate": "/api/ocelot/{postId}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 8001 } ], "UpstreamPathTemplate": "/ocelot/ratelimit/{postId}", "UpstreamHttpMethod": [ "Get" ], "Priority": 2, "RateLimitOptions": { "ClientWhiteList": [ "markadmin" ], "EnableRateLimiting": true, "Period": "1m", "PeriodTimespan": 10, "Limit": 5 } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxdyg.html