這幾篇將API安全的 流控、認證、審計、授權 簡單的過一遍,對這些概念先有個初步印象。后邊還會詳細講解。
本篇說API安全之流控~第一印象。
一、概念
流控,流量控制,只放系統能處理的請求的數量過去,處於api安全鏈路的第一關。
為什么要做流控?保證系統的可用性,防止大流量把系統給壓死。流控的位置做在認證、審計、授權等整個安全機制的最前邊,提前控制流量,避免其他無用的資源浪費。
如果沒有流控放在第一道檔線,攻擊者弄一堆肉雞,發起DDOS攻擊,即使你后邊的認證、審計、授權 做得再好,也可能把你的服務壓死。
比如系統每秒只能處理500個請求,那么每秒就放500個請求過去,多了的請求直接拒絕掉,這樣的話系統不會被壓死。實際中的流控是非常復雜的,不是簡單地設個數就完了。
二,流控做在哪?
實際開發中限流可以在很多地方做的, 比如:
1,在負載均衡上做,
2,在反向代理上做,
在負載均衡或反向代理層面上做限流,實際上一般是針對真個集群做的限流。比如你一個用戶服務,實際部署的時候可能是四個機器或者八個機器的集群,在負載均衡或反向代理層面做的集群就是真對整個集群做的限流,整個集群能撐多少流量,做個限流。
3,在自己的應用代碼上做。
只針對單個應用的節點做的流控,跟反向代理、負載均衡做的限流不是一個維度的,如果能配的話,把兩邊都配上,他們並不沖突。后邊會介紹通過框架控制集群的流量。
三,使用Guava做簡單的限流
在pom引入最新的guava依賴
<!-- https://mvnrepository.com/artifact/com.google.guava/guava --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>28.1-jre</version> </dependency>
項目:
寫一個限流的過濾器:
package com.nb.security.filter; import com.google.common.util.concurrent.RateLimiter; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * 繼承 OncePerRequestFilter 保證過濾器里的邏輯在一個請求里只會被過濾一次 * 在SpringBoot里,任何實現了Filter接口的類,SpringBoot會自動把它加到web應用的過濾器鏈里,只要聲名為Component就行了 */ @Order(1)//執行順序 @Component public class RateLimitFilter extends OncePerRequestFilter {// //每秒1個請求的限流器 private RateLimiter rateLimiter = RateLimiter.create(1); protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { System.err.println("++++流控++++"); if (rateLimiter.tryAcquire()) { //如果沒達到限流閾值,放行 filterChain.doFilter(request, response); } else { response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());//429請過過多 response.getWriter().write("too many request!"); response.getWriter().flush(); return ; } } }
調用用戶查詢接口,使勁刷新,就返回429
這個是個簡單的例子, 實際中的流控,比這個要復雜的多,比如可以根據用戶來限流,VIP用戶每秒500請求,普通用戶每秒50請求,這樣大量請求過來了,VIP用戶沒什么感覺可以正常訪問,普通用戶就被拒絕了。
代碼:https://github.com/lhy1234/springcloud-security/tree/master/nb-user-api
++++++++++++++++++++++++分割線++++++++++++++++++++++++
小結:
1,流控概念:流量控制
2,流控位置:負載均衡、反向代理、應用邏輯
3,guava做簡單的限流,對限流有個第一印象