NetCore Ocelot 之 Rate Limiting

Ocelot supports rate limiting of upstream requests so that your downstream services do not become overloaded.

OK so to get rate limiting working for a Route you need to add the following json to it.

"RateLimitOptions": {
        "ClientWhiteList": [],
        "EnableRateLimiting": true,
        "Period": "10s", //1s, 5m, 1h, 1d
        "PeriodTimespan": 10, //retry after n second/seconds
        "Limit": 3
      }

ClientWhiteList - This is an array that contains the whitelist of the client. It means that the client in this array will not be affected by the rate limiting.

EnableRateLimiting- This value specifies enable endpoint rate limiting.

Period - This value specifies the period that the limit applies to, such as 1s, 5m,1h,1d and so on. If you make more requests in the period than the limit allows then you need to wait for PeriodTimeSpan to elapse before you make another request.

PeriodTimespan - This value specifies that we can retry after a certain numbers of seconds.

Limit - This value specifies the maximum number of requests that a client can make in a defined period.

You can also set the following in the GlobalConfiguration part of ocelot.json

"RateLimitOptions": {
      "ClientIdHeader": "IgnoreRateLimit", //request header key
      "QuotaExceededMessage": "The requests has reached the quota.", //The customized prompt
      "RateLimitCounterPrefix": "ocelotratelimit",
      "DisableRateLimitHeaders": false,
      "HttpStatusCode": 666
    }

ClientIdHeader - Allows you to specify the header that should be used to identity clients. By default it is "ClientId". 

DisableRateLimitHeader  - This value specifies whether X-Rate-Limit and Retry-After headers are disalbled.

QuotaExceededMessage - This value specifies the exceeded message.

HttpStatusCode -  This value specifies the returned HTTP Status code when rate limiting occurs.

OK,以上是Ocelot关于RateLimit的一些配置项详解,接下里实战介绍

ocelot.json Route配置如下

{
      "DownstreamPathTemplate": "/api/service1",
      "DownstreamScheme": "https",
      "DownstreamHttpMethod": "Get",
      "UpstreamHttpMethod": [ "Options", "Get", "Post", "Put", "Delete" ],
      "UpstreamPathTemplate": "/Ocelot/service1",
      //"UpstreamHost": "localhost",//404 Not found
      "UseServiceDiscovery": true,
      "ServiceName": "serviceA",
      /*
      LeastConnection
      RoundRobin
      NoLoadBalance
      */
      "LoadBalancerOptions": {
        "Type": "CustomRandomLoadBalancer"
      },
      "RateLimitOptions": {
        "ClientWhiteList": [],
        "EnableRateLimiting": true,
        "Period": "10s", //1s, 5m, 1h, 1d
        "PeriodTimespan": 10, //retry after n second/seconds
        "Limit": 3
      },
      "authenticationoptions": {
        "authenticationproviderkey": "authenticationkey",
        "allowedscopes": []
      },
      "Key": "service1",
      "Priority": 11
    }

通过Consul服务注册发现注册service,ServiceName为serviceA,端口分别5001,5002当然这里注册一个service即可。

 Consul中查看services

 启动 consul, ocelot 及service api, 在10s之内访问次数超过三次之后测试Rate Limit

 Notes: 如果想启用RateLimit白名单,可以通过指定Global.ocelot.json中配置的ClientIdHeader key的value。

"RateLimitOptions": {
        "ClientWhiteList": [ "NoLimitedAPI" ],
        "EnableRateLimiting": true,
        "Period": "10s", //1s, 5m, 1h, 1d
        "PeriodTimespan": 10, //retry after n second/seconds
        "Limit": 3
      }

为了测试Rate Limit WhiteList 通过中间件的方式给每个Request指定ClientIdHeader及value

app.Use((httpContext, requestDelegate) =>
{
    if (!httpContext.Request.Headers.TryGetValue("IgnoreRateLimit", out Microsoft.Extensions.Primitives.StringValues value))
        httpContext.Request.Headers.Add("IgnoreRateLimit", "NoLimitedAPI");
    return requestDelegate.Invoke(httpContext);
});

重新启动Ocelot, 发现request中加了指定key value header的请求不在受Rate Limit影响(这里只是为了测试给所有的request都加了key value,实际开发中可以根据controller或attribute灵活处理)。

posted @ 2023-10-08 14:51  云霄宇霁  阅读(24)  评论(0编辑  收藏  举报