Spring?Cloud?Gateway服務網關限流問題及解決
網關是所有請求的公共入口,所以可以在網關進行限流,而且限流的方式也很多,我們本次采用前面學過的 Sentinel 組件來實現網關的限流。
Sentinel 支持對 SpringCloud Gateway、Zuul等主流網關進行限流。
從1.6.0版本開始,Sentinel提供了SpringCloud Gateway的適配模塊,可以提供兩種資源維度的限流:
- route維度:即在Spring配置文件中配置的路由條目,資源名為對應的routeld;
- 自定義API維度:用戶可以利用Sentinel提供的API來自定義一些API分組;
route限流
導入依賴
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId> </dependency>
編寫配置類
基于Sentinel的Gateway限流是通過其提供的Filter來完成的,使用時只需注入對應的SentinelGatewayFilter
實例以及SentinelGatewayBlockExceptionHandler
實例即可。
@Configuration public class GatewayConfiguration { private final List<ViewResolver> viewResolvers; private final ServerCodecConfigurer serverCodecConfigurer; public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider, ServerCodecConfigurer serverCodecConfigurer) { this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList); this.serverCodecConfigurer = serverCodecConfigurer; } //初始化一個限流的過濾器 @Bean @Order(Ordered.HIGHEST_PRECEDENCE) public GlobalFilter sentinelGatewayFilter() { return new SentinelGatewayFilter(); } //配置初始化的限流參數 @PostConstruct public void initGatewayRules() { Set<GatewayFlowRule> rules = new HashSet<>(); rules.add(new GatewayFlowRule("shop-product")//資源名稱,對應路由id .setCount(1)//限流閥值 .setIntervalSec(1)//統計時間窗口,單位是秒,默認是1秒 ); GatewayRuleManager.loadRules(rules); } //配置限流異常處理器 @Bean @Order(Ordered.HIGHEST_PRECEDENCE) public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() { return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer); } //自定義限流異常頁面 @PostConstruct public void initBlockHandlers() { BlockRequestHandler blockRequestHandler = new BlockRequestHandler() { @Override public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) { Map map= new HashMap<>(); map.put("code", 0); map.put("message", "接口被限流了"); return ServerResponse .status(HttpStatus.OK) .contentType(MediaType.APPLICATION_JSON_UTF8) .body(BodyInserters.fromObject(map)); } } ; GatewayCallbackManager.setBlockHandler(blockRequestHandler); } }
其中,GatewayFlowRule 網關限流規(guī)則中提供了如下屬性:
resource
:資源名稱,可以是網關中的route名稱或者用戶自定義的API分組名稱。resourceMode
:資源模型,限流規(guī)則是針對API Gateway的 route(RESOURCE_MODE_ROUTE_ID)
還是用戶在Sentinel 中定義的API分組(RESOURCE_MODE_CUSTOM_API_NAME)
,默認route。grade
:限流指標維度,同限流規(guī)則的 grade 字段。count
:限流閾值。intervalSec
:統計時間窗口,單位是秒, 默認是1 秒。controlBehavior
:流量整形的控制效果,同限流規(guī)則的controlBehavior字段,目前支持快速失敗和勻速排隊兩種模式,默認快速失敗。burst
:應對突發(fā)請求時額外允許的請求數目。maxQueueingTimeoutMs
:勻速排隊模式下的最長排隊時間,單位是毫秒,僅在勻速排隊模式下生效。paramItem
:參數限流配置。若不提供,則代表針對參數進行限流,該網關規(guī)則將會被轉換成普通流控規(guī)則;否則會轉換熱點規(guī)則。其中的字段如下:arseStrategy
:從請求中提取參數的策略,目前支持提取來源IP(PARAM_PARSE_STRATEGY_CLIENT_IP)、Host(PARAM_PARSE_STRATEGY_HOST)、任意Header(PARAM_PARSE_STRATEGY_HEADER)和任意URL 參數(PARAM_PARSE_STRATEGY_URL_PARAM)四種模式。fieldName
:若提取策略選擇Header模式或者URL參數模式,則需要指定對應的Header名稱或URL參數名稱。pattern
和matchStrategy
:為后續(xù)參數匹配特性預留,目前末實現。
測試
在一秒鐘內多次訪問http://localhost:7000/product/product/1?token=1232
就可以看到限流啟作用了。
自定義API分組
自定義API分組是一種更細粒度的限流規(guī)則定義
//配置初始化的限流參數 @PostConstruct public void initGatewayRules() { Set<GatewayFlowRule> rules = new HashSet<>(); rules.add(new GatewayFlowRule("shop_product_api").setCount(1).setIntervalSec(1)); rules.add(new GatewayFlowRule("shop_order_api").setCount(1).setIntervalSec(1)); GatewayRuleManager.loadRules(rules); } //自定義API分組 @PostConstruct private void initCustomizedApis(){ Set<ApiDefinition> definitions = new HashSet<>(); //定義小組1 ApiDefinition api1 = new ApiDefinition("shop_product_api") .setPredicateItems(new HashSet<ApiPredicateItem>(){{ //以/product/product/api1開頭的請求 add(new ApiPathPredicateItem().setPattern("/product/product/**") .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX)); }}); //定義小組2 ApiDefinition api2 = new ApiDefinition("shop_order_api") .setPredicateItems(new HashSet<ApiPredicateItem>(){{ //完全匹配/order/order2/message add(new ApiPathPredicateItem().setPattern("/order/order2/message")); }}); definitions.add(api1); definitions.add(api2); GatewayApiDefinitionManager.loadApiDefinitions(definitions); }
在一秒鐘內多次訪問http://localhost:7000/product/product/1?token=1232
也可以看到限流啟作用了。
總結
到這兒,Gateway 服務網關限流的內容就已經介紹完了。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
spring+springmvc整合mabytis時mapper注入失敗問題解決方法
這篇文章主要介紹了spring+springmvc整合mabytis時mapper注入失敗問題解決方法 ,需要的朋友可以參考下2017-08-08解決IDEA Gradle構建報錯''Cause: zip END header not found''
這篇文章主要介紹了解決IDEA Gradle構建報錯"Cause: zip END header not found"的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02Sublime Text 打開Java文檔中文亂碼的解決方案
這篇文章主要介紹了Sublime Text 中文亂碼的解決方案,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2020-12-12