Spring Cloud 服務限流/API限流(Zuul+RateLimiter)

一、前言

1、什麼是RateLimiter、Spring Cloud Zuul RateLimiter?

RateLimiter是Google開源的實現了令牌桶算法的限流工具(速率限制器)。http://ifeve.com/guava-ratelimiter/

Spring Cloud Zuul RateLimiter結合Zuul對RateLimiter進行了封裝,通過實現ZuulFilter提供了服務限流功能

限流粒度/類型 說明
Authenticated User 針對請求的用戶進行限流
Request Origin 針對請求的Origin進行限流
URL 針對URL/接口進行限流
Service 針對服務進行限流,如果沒有配置限流類型,則此類型生效

https://github.com/marcosbarbero/spring-cloud-zuul-ratelimit

2、本篇主要內容

  • 服務限流配置示例與說明
  • URL限流配置示例與說明
  • Zull集羣服務限流說明(+Redis)
  • Spring Cloud Zuul RateLimiter參數介紹

3、本篇環境信息

框架 版本
Spring Boot 2.0.0.RELEASE
Spring Cloud Finchley.RELEASE
Zuul 1.3.1
JDK 1.8.x

4、準備工作

參考上一篇:https://ken.io/note/spring-cloud-zuul-quickstart
基於源碼:https://github.com/ken-io/springcloud-course/tree/master/chapter-08

  • 準備Eureka Server、服務提供者

啓動Eureka Server: http://localhost:8800
啓動Test Service:http://localhost:8602

二、服務限流(Zuul+RateLimiter)

基於上一篇中zuul項目的源碼進行修改即可:https://github.com/ken-io/springcloud-course/tree/master/chapter-08/zuul

  • 引入spring-cloud-zuul-ratelimit
<dependency>
    <groupId>com.marcosbarbero.cloud</groupId>
    <artifactId>spring-cloud-zuul-ratelimit</artifactId>
    <version>2.0.4.RELEASE</version>
</dependency>

1、默認服務限流策略

  • 修改 application.yml 配置限流策略
zuul:
  ratelimit:
    enabled: true
    default-policy:
      limit: 1
      quota: 2
      refresh-interval: 3

以上配置表示啓用限流策略,並且所有服務在3秒內只能有1次請求且所有請求時間總和不得超過2秒

  • 限流測試

啓動zuul項目,然後訪問 http://localhost:8888/testservice?token=ken
3秒內訪問兩次,就會看到錯誤頁面

image

錯誤信息:type=Too Many Requests, status=429
這說明3秒內的>1次的訪問已經被限流策略擋掉

2、爲指定服務單獨配置限流策略

  • 修改 application.yml 配置限流策略
zuul:
  ratelimit:
    enabled: true
    default-policy:
      limit: 1
      quota: 1
      refresh-interval: 3
    policies:
      testservice:
        limit: 10
        quota: 50
        refresh-interval: 60

以上配置單獨爲testservice配置了限流策略。60秒內訪問次數不得查過10次且訪問時間這不得超過50秒。

雖然我們也同時配置了默認限流策略,而且默認限流策略比testservice的限流策略還要更嚴格,但是這個限流並不會衝突。因爲一旦我們爲某個服務單獨配置了限流策略,那麼只有這個單獨配置的限流策略會對該服務生效。

3、基於URL的限流策略

  • 修改 application.yml 配置限流策略
zuul:
  ratelimit:
    enabled: true
    default-policy:
      limit: 1
      quota: 1
      refresh-interval: 3
    policies:
      testservice:
        limit: 10
        quota: 50
        refresh-interval: 60
        type: url

以上配置只是在testservice的策略上增加了type參數的設置。(當然也可以在默認策略加這個參數)。

那麼這個策略就變成了:每個Url60秒內訪問次數不得超過10次且總計訪問時間這不得超過50秒。

  • 訪問測試

啓動zuul項目,然後訪問: http://localhost:8888/testservice?token=ken
達到限流閾值後,訪問:
http://localhost:8888/testservice/plus?token=ken&numA=1&numB=2

依然可以正常訪問。
另外,需要值得注意的是,?後面的參數是不會作爲限流的key的。
http://localhost:8888/testservice?token=ken , http://localhost:8888/testservice?token=ken.io 會被作爲同一個url進行限流

如果zuul-ratelimiter的限流粒度/方式不能滿足你的需求,你可以選擇自定義ZuulFilter集成RateLimiter去做限流。

三、Zuul集羣服務限流(Zuul+RateLimiter+Redis)

RateLimiter的限流數據是默認以ConcurrentHashMap方式存儲在內存中的,
當我們部署了Zuul集羣的時候,就會影響我們的限流策略了。我們可以將限流數據存儲在Redis中,這樣就可以集中記錄各個Zuul節點的限流數據,來保證限流的準確性。

1、部署Reids Server

參考:https://ken.io/note/centos7-redis4-setup

2、引入 Spring Data Redis

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.0.4.RELEASE</version>
</dependency>

3、配置Redis連接

修改application.yml

spring:
  redis:
    host: 192.168.88.11
    port: 6379

4、配置RateLimiter數據存儲方式

zuul:
  ratelimit:
    enabled: true
    repository: redis
    default-policy:
      limit: 1
      quota: 1
      refresh-interval: 3
    policies:
      testservice:
        limit: 10
        quota: 50
        refresh-interval: 60
        type: url

四、備註

Zuul-RateLimiter參數說明

  • Zuul-RateLimiter基本配置項
配置項 可選值 說明
enabled true/false 是否啓用限流
behind-proxy true/false 翻了源碼,沒發現有使用。。。作者也沒說明。。。
key-prefix String 限流key前綴
repository CONSUL, REDIS, JPA, BUCKET4J_JCACHE, BUCKET4J_HAZELCAST, BUCKET4J_INFINISPAN, BUCKET4J_IGNITE, IN_MEMORY 限流數據的存儲方式,默認是:IN_MEMORY
default-policy 默認策略
policies 自定義策略
postFilterOrder postFilter過濾順序
preFilterOrder preFilter過濾順序
  • Policy限流策略配置項說明
說明
limit 單位時間內請求次數限制
quota 單位時間內累計請求時間限制(秒),非必要參數
refresh-interval 單位時間(秒),默認60秒
type 限流方式:ORIGIN, USER, URL
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章