spring cloud網關經過Zuul RateLimit 限流配置

在日常項目中爲了防止一些沒有token訪問的API被大量無限的調用,須要對一些服務進行API限流。就比如拿一些註冊或者發驗證碼的一些接口,若是被惡意無限的調用,多少會形成一些費用的產生,發短信或者郵件都是一些第三方接口,次數越多,固然費用也就越多了,嚴重的直接致使服務崩潰。spring cloud api-gateway中引入限流的配置仍是必須的。api

引入依賴

在pom文件中引入Zuul RateLimit的依賴this

<dependency>
    <groupId>com.marcosbarbero.cloud</groupId>
    <artifactId>spring-cloud-zuul-ratelimit</artifactId>
    <version>1.3.2.RELEASE</version>
</dependency>

配置信息

更詳細的配置解讀下面有寫,這裏只是簡單配置一下,如下這個配置就能夠對服務進行限流了
zuul:
  routes: 你的路由配置
    test:
      path: 
      serviceId: 
  ratelimit:
    enabled: true
    policies:
      test: 路由名
        limit: 限制次數
        refresh-interval: 刷新時間
        type: 類型

RateLimit源碼簡單分析

本地讓本身的一個服務配置爲一分鐘內該服務的API只能訪問十次,超過十次,網關就會報錯url

zuul:
  routes:
    test:
      path: /api/test/**
      serviceId: hscf-cloud-test-9457
  ratelimit:
    enabled: true
    policies:
      test:
        limit: 10
        refresh-interval: 60
        type: origin  限流方式

下面經過源碼簡要分析一下代理

RateLimit類是繼承ZuulFilter,內中的變量不難看出就是咱們在yml文件中配置的屬性值。RateLimit內中的部分源碼,filterType爲「pre」表示在每個API訪問以前進行攔截,LIMIT_HEADER,REMAINING_HEADER,RESET_HEADER這三個變量應該就是獲取咱們配置的訪問次數,還有記錄該時間內剩餘的訪問次數。code

public class RateLimitFilter extends ZuulFilter {
    public static final String LIMIT_HEADER = "X-RateLimit-Limit";
    public static final String REMAINING_HEADER = "X-RateLimit-Remaining";
    public static final String RESET_HEADER = "X-RateLimit-Reset";

    public String filterType() {
        return "pre";
    }
    public int filterOrder() {
        return -1;
    }
    public boolean shouldFilter() {
        return this.properties.isEnabled() && this.policy(this.route()).isPresent();
    }

主體邏輯run()中進行判斷。先經過this.policy(route).ifPresent((policy)判斷policy配置信息是否存在,存在的話會讀
取到當前的限制值,還剩餘的限制值,最終判斷剩餘的限制值是否小於0,小於0的話就會報出太多請求的異常
TOO_MANY_REQUESTS(429, "Too Many Requests")繼承

public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletResponse response = ctx.getResponse();
        HttpServletRequest request = ctx.getRequest();
        Route route = this.route();
        this.policy(route).ifPresent((policy) -> {
            String key = this.rateLimitKeyGenerator.key(request, route, policy);
            Rate rate = this.rateLimiter.consume(policy, key);
            response.setHeader("X-RateLimit-Limit", policy.getLimit().toString());
            response.setHeader("X-RateLimit-Remaining", String.valueOf(Math.max(rate.getRemaining().longValue(), 0L)));
            response.setHeader("X-RateLimit-Reset", rate.getReset().toString());
            if(rate.getRemaining().longValue() < 0L) {
                ctx.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
                ctx.put("rateLimitExceeded", "true");
                throw new ZuulRuntimeException(new ZuulException(HttpStatus.TOO_MANY_REQUESTS.toString(), HttpStatus.TOO_MANY_REQUESTS.value(), (String)null));
            }
        });
        return null;
    }
。。。。。。

控制檯的異常信息,異常code爲429,也就是太多請求的異常:TOO_MANY_REQUESTS(429, "Too Many Requests")token

RateLimit詳細的配置信息解讀

zuul:

    ratelimit:

        key-prefix: your-prefix  #對應用來標識請求的key的前綴

        enabled: true

        repository: REDIS  #對應存儲類型(用來存儲統計信息)

        behind-proxy: true  #代理以後

        default-policy: #可選 - 針對全部的路由配置的策略,除非特別配置了policies

             limit: 10 #可選 - 每一個刷新時間窗口對應的請求數量限制

             quota: 1000 #可選-  每一個刷新時間窗口對應的請求時間限制(秒)

              refresh-interval: 60 # 刷新時間窗口的時間,默認值 (秒)

               type: #可選 限流方式

                    - user

                    - origin

                    - url

          policies:

                myServiceId: #特定的路由

                      limit: 10 #可選- 每一個刷新時間窗口對應的請求數量限制

                      quota: 1000 #可選-  每一個刷新時間窗口對應的請求時間限制(秒)

                      refresh-interval: 60 # 刷新時間窗口的時間,默認值 (秒)

                      type: #可選 限流方式

                          - user

                          - origin

                          - url
  • url類型的限流就是經過請求路徑區分
  • origin是經過客戶端IP地址區分
  • user是經過登陸用戶名進行區分,也包括匿名用戶

目前只是將網關中的限流方式使用連起來,源碼中的原理知道了一下,後續能夠繼續進行擴展,能夠針對請求上的參數進行請求攔截限流接口

相關文章
相關標籤/搜索