網關(Gateway)是微服務中不可缺少的一部分,它是微服務中提供了統一訪問地址的組件,充當了客戶端和內部微服務之間的中介。網關主要負責流量路由和轉發,將外部請求引導到相應的微服務實例上,同時提供一些功能,如身份認證、授權、限流、監控、日志記錄等。
網關的主要作用有以下幾個:
為了保護后端微服務免受突發高流量請求的影響,確保系統的穩定和可靠性,所以在網關層必須“限流”操作。
限流是一種流量控制的策略,用于限制系統處理請求的速率或數量,以保護系統免受過載或攻擊的影響。通過限制請求的數量或速率,可以平衡系統和資源之間的壓力,確保系統在可接受的范圍內運行。
限流的常見策略通常有以下幾種:
當然,我們也可以在程序中使用多種策略混合限流,以保證內部微服務的穩定性。
了解了網關和限流的相關內容之后,我們以目前主流的網關組件 Spring Cloud Gateway 為例,來實現一下限流功能。
Spring Cloud Gateway 實現限流的方式有兩種:
那既然 Spring Cloud Gateway 中已經內置了限流功能,那我們接下來就來看 Spring Cloud Gateway 內置限流是如何實現的?
Spring Cloud Gateway 內置的限流器為 RequestRateLimiter GatewayFilter Factory,官網說明文檔:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#the-requestratelimiter-gatewayfilter-factory
Spring Cloud Gateway 支持和 Redis 一起來實現限流功能,它的實現步驟如下:
具體實現如下。
在項目的 pom.xml 中,添加以下配置信息(添加 Redis 框架依賴支持):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis-reactive</artifactId></dependency>
接下來我們新建一個限流規則定義類,實現一下根據 IP 進行限流的功能,實現示例代碼如下:
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;import org.springframework.stereotype.Component;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;@Componentpublic class IpAddressKeyResolver implements KeyResolver { @Override public Mono<String> resolve(ServerWebExchange exchange) { return Mono.just(exchange.getRequest().getRemoteAddress(). getHostString()); }}
這一步其實是在配置限流器的限流參數 KeyResolver,也就是限流功能的依賴“憑證”。
“
PS:當然,我們還可以通過 URL、方法名、用戶等進行限流操作,只需要修改此步驟中的限流憑證,也就是 KeyResolver 即可。
”
在網關項目的配置文件中,添加以下配置信息:
spring: cloud: gateway: routes: - id: retry uri: lb://nacos-discovery-demo predicates: - Path=/retry/** filters: - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 1 redis-rate-limiter.burstCapacity: 1 keyResolver: '#{@ipAddressKeyResolver}' # spEL表達式 data: redis: host: 127.0.0.1 port: 16379 database: 0
其中,name 必須等于“RequestRateLimiter”內置限流過濾器,其他參數的含義如下:
“
SpEL(Spring Expression Language,Spring 表達式語言)是 Spring 框架中用于提供靈活、強大的表達式解析和求值功能的統一表達式語言。它可以在運行時動態地解析和求值字符串表達式,通常用于配置文件中的屬性值、注解、XML 配置等地方。
”
當 Spring Cloud Gateway 配合 Redis 實現限流的時候,它對于 Redis 的版本是有要求的,因為它在限流時調用了一個 Redis 高版本的函數,所以 Redis Server 版本太低,限流無效,Redis Server 最好是 5.X 以上。
最后,我們頻繁的訪問:http://localhost:10086/retry/test 就會看到如下限流信息:
Spring Cloud Gateway 內置限流功能使用的算法是令牌桶限流算法。
令牌桶限流算法:令牌按固定的速率被放入令牌桶中,桶中最多存放 N 個令牌(Token),當桶裝滿時,新添加的令牌被丟棄或拒絕。當請求到達時,將從桶中刪除 1 個令牌。令牌桶中的令牌不僅可以被移除,還可以往里添加,所以為了保證接口隨時有數據通過,必須不停地往桶里加令牌。由此可見,往桶里加令牌的速度就決定了數據通過接口的速度。我們通過控制往令牌桶里加令牌的速度從而控制接口的流量。 令牌桶執行流程如下圖所示:
常見的限流算法還有:計數器算法、滑動計數器算法、漏桶算法等,更多介紹參考我之前寫個的文章:https://www.javacn.site/interview/springcloud/loadbalancer.html。
Spring Cloud Gateway 執行過程如下圖所示:
從圖中可以看出,所有的請求來了之后,會先走過濾器,只有過濾器通過之后,才能調用后續的內部微服務,這樣我們就可以通過過濾器來控制微服務的調用,從而實現限流功能了。
Spring Cloud Gateway 過濾器是基于令牌桶算法來限制請求的速率,該過濾器根據配置的限流規則,在指定的時間窗口內分配一定數量的令牌,每個令牌代表一個允許通過的請求,當一個請求到達時,如果沒有可用的令牌,則請求將被阻塞或拒絕。
令牌桶的執行過程如下:
主流網關組件 Spring Cloud Gateway 實現限流的方式主要有兩種:內置限流過濾器和外部限流組件,如 Sentinel、Hystrix 等。而最簡單的限流功能,我們只需要使用 Spring Cloud Gateway 過濾器 + Redis 即可(實現),其使用的是令牌桶的限流算法來實現限流功能的。
本文鏈接:http://www.www897cc.com/showinfo-26-31548-0.html面試官:網關如何實現限流?
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 深入剖析SpringBoot底層原理
下一篇: C++中的內聯函數:提高程序效率