Spring Cloud Zuul微服務網關的API限流(轉)


https://blog.csdn.net/ta_ab/article/details/77984312

API限流

微服務開發中有時需要對API做限流保護,防止網絡攻擊,比如做一個短信驗證碼API,限制客戶端的請求速率能在一定程度上抵御短信轟炸攻擊,降低損失。

微服務網關是每個請求的必經入口,非常適合做一些API限流、認證之類的操作,這里有一個基於zuul微服務網關的API限流庫:

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

使用方法

比如我們要對user-service這個服務進行限流,限制每個請求源每分鍾最多只能請求10次。

首先在項目中添加 spring-cloud-zuul-ratelimit 依賴:

<dependency> <groupId>com.marcosbarbero.cloud</groupId> <artifactId>spring-cloud-zuul-ratelimit</artifactId> <version>1.5.0.RELEASE</version> </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

然后再添加如下配置即可:

zuul:
  ratelimit:
    enabled: true
    behind-proxy: true
    policy-list:
      user-service:
        - limit: 10 refresh-interval: 60 type: - user - origin - url
  • 測試客戶端如果60s內請求超過10次,服務端就拋出異常,一分鍾后又可以正常請求

  • 某個IP的客戶端被限流並不影響其他客戶端,即API網關對每個客戶端限流是相互獨立的

限流數據存儲

對API限流是基於Zuul過濾器完成的,默認情況下限流數據是記錄在內存中的,實際上是用ConcurrentHashMap保存,當然也提供了多種存儲方式,包括Redis、Consul、Spring Data JPA,使用這三種存儲方式要添加相關依賴。

然后再添加存儲配置,比如使用Redis的配置:

zuul: ratelimit: repository: Redis
  • 1
  • 2
  • 3

原理分析

限流攔截時機

限流過濾器是在請求被轉發之前調用的

    @Override public String filterType() { return "pre"; }

 

限流類型

限流類型主要包括url、origin、user三種

   if (types.contains(URL)) { joiner.add(route.getPath()); } if (types.contains(ORIGIN)) { joiner.add(getRemoteAddr(request)); } if (types.contains(USER)) { joiner.add(request.getUserPrincipal() != null ? request.getUserPrincipal().getName() : ANONYMOUS); }
  • url類型的限流就是通過請求路徑區分

  • origin是通過客戶端IP地址區分

  • user是通過授權用戶進行區分,也包括匿名用戶

  • 可以多個限流類型結合使用

  • 如果不配置限流類型,就不做以上區分

攔截限流請求

在過濾器的run方法中判斷請求剩余次數,小於0就攔截請求:

   if (rate.getRemaining() < 0) { ctx.setResponseStatusCode(TOO_MANY_REQUESTS.value()); ctx.put("rateLimitExceeded", "true"); throw new ZuulRuntimeException(new ZuulException(TOO_MANY_REQUESTS.toString(), TOO_MANY_REQUESTS.value(), null)); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

可以看到,單位時間內剩余請求次數小於0時拋出ZuulRuntimeException,直接返回客戶端TOO_MANY_REQUESTS異常消息,達到攔截請求的效果。

示例代碼

https://github.com/yunTerry/spring-cloud-netflix


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM