【Spring Cloud Alibaba】Sentinel 流量控制
- 1 搭建SpringCloud Alibaba Sentinel控制台
- 2 项目集成
- 3 降级
-
- 3.1 接口降级
-
- 3.1.2 硬编码限流
- 3.1.2 控制面板限流
- 3.2 RestTemplate 降级
- 3.3 Feign 降级
- 4 Sentinel 存储
-
- 4.1 SpringCloud Alibaba Sentinel 结合 Nacos
- 5 Gateway 结合 Sentinel
-
- 5.1 添加依赖
- 5.2 硬编码配置
- 5.3 JSON文件配置方式
- 5.3 Nacos存储配置方式
Sentinel是面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助您保障微服务的稳定性
SpringCloud Alibaba Sentinel流量控制方向
- 资源的调用关系,例如资源的调用链路,资源和资源之间的关系
- 运行指标,例如QPS、线程池、系统负载等
- 控制的效果,例如直接限流、冷启动、排队等
1 搭建SpringCloud Alibaba Sentinel控制台
Sentinel提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能
获取并启动Sentinel Dashboard(控制台)
1.下载控制台Jar包: https://github.com/alibaba/Sentinel/releases
2. java -Dserver.port=7777 -Dcsp.sentinel.dashboard.server=localhost:7777 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.1.jar
3.从 Sentinel 1.6.0起,Sentinel Dashboard引入了基本的登录功能,默认的用
户名密码都是sentinel
2 项目集成
创建子模块,配置maven
e-commerce-sentinel-client jar 8 8 e-commerce-sentinel-client Sentinel Client com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery com.alibaba.cloud spring-cloud-starter-alibaba-sentinel org.springframework.cloud spring-cloud-starter-openfeign com.alibaba.csp sentinel-datasource-nacos cn.flowboot.e.commerce e-commerce-common org.springframework.boot spring-boot-starter-web ${artifactId} org.springframework.boot spring-boot-maven-plugin repackage
3 降级
SpringCloud Alibaba Sentinel对降级功能的支持
3.1 接口降级
3.1.2 硬编码限流
FlowRuleCodeController
package cn.flowboot.e.commerce.controller; import cn.flowboot.e.commerce.block.handler.MyBlockHandler; import cn.flowboot.e.commerce.vo.CommonResponse; import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockException; import com.alibaba.csp.sentinel.slots.block.RuleConstant; import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; @Slf4j @RestController @RequestMapping("/code") public class FlowRuleCodeController { @PostConstruct public void init(){ //流控规则集合 List flowRules = new ArrayList(); //创建流控规则 FlowRule flowRule = new FlowRule(); //设置流控规则QPS,限流阈值类型CQPS,并发线程数 flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS); //流量控制手段 flowRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); //设置受保护的资源 flowRule.setResource("flowRuleCode"); //设置受保护的资源的阈值 flowRule.setCount(1); flowRules.add(flowRule); //加载配置好的规则 FlowRuleManager.loadRules(flowRules); } @GetMapping("/flow-rule") //@SentinelResource(value = "flowRuleCode") //@SentinelResource(value = "flowRuleCode",blockHandler = "handleException") @SentinelResource(value = "flowRuleCode",blockHandler = "myHandleException",blockHandlerClass = MyBlockHandler.class) public CommonResponse flowRuleCode(){ log.info("request flowRuleCode"); return CommonResponse.success(); } public CommonResponse handleException(BlockException e){ log.error("has block exception : [{}]", JSONObject.toJSONString(e.getRule())); return CommonResponse.fail("flow rule exception",e.getClass().getCanonicalName()); } }
上文flowRuleCode方法注解使用到通用限流处理MyBlockHandler ,可切换注释使用不同使用策略
package cn.flowboot.e.commerce.block.handler; import cn.flowboot.e.commerce.vo.CommonResponse; import com.alibaba.csp.sentinel.slots.block.BlockException; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; @Slf4j public class MyBlockHandler { public static CommonResponse myHandleException(BlockException e){ log.error("has block exception : [{}], [{}]", JSONObject.toJSONString(e.getRule()),e.getRuleLimitApp()); return CommonResponse.fail("trigger flow rule exception",e.getClass().getCanonicalName()); } }
3.1.2 控制面板限流
RateLimitController
package cn.flowboot.e.commerce.controller; import cn.flowboot.e.commerce.block.handler.MyBlockHandler; import cn.flowboot.e.commerce.vo.CommonResponse; import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockException; import com.alibaba.csp.sentinel.slots.block.RuleConstant; import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; @Slf4j @RestController @RequestMapping("/rate") public class RateLimitController { @GetMapping("/by-resource") @SentinelResource(value = "byResource",blockHandler = "myHandleException",blockHandlerClass = MyBlockHandler.class) public CommonResponse byResource(){ log.info("coming in rate limit controller by resource"); return CommonResponse.success(); } @GetMapping("/by-url") @SentinelResource(value = "byUrl") public CommonResponse byUrl(){ log.info("coming in rate limit controller by Url"); return CommonResponse.success("byUrl"); } }
添加流控规则,两个相同名称,一个是硬编码指定,一个是动态添加(保存JVM内存中)
3.2 RestTemplate 降级
Sentinel支持对RestTemplate 服务调用进行保护,实现流控降级和异常降级
# 开启或关闭 @SentinelRestTemplate resttemplate: sentinel: enabled: true
SentinelFallbackController :通过@SentinelResource配置异常处理
package cn.flowboot.e.commerce.controller; import cn.flowboot.e.commerce.conf.RestTemplateExceptionHandler; import cn.flowboot.e.commerce.fallback.MyFallbackHandler; import cn.flowboot.e.commerce.vo.CommonResponse; import com.alibaba.csp.sentinel.annotation.SentinelResource; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import java.util.Map; @Slf4j @RequiredArgsConstructor @RestController @RequestMapping("/fallback") public class SentinelFallbackController { //注入普通 private final RestTemplate restTemplate; @GetMapping("/remote/consumer") @SentinelResource( value = "remoteConsumerFallback", fallback = "remoteConsumerFallback", fallbackClass = { MyFallbackHandler.class } ) public CommonResponse remoteConsumer(){ String requestUrL = "http://localhost:8500/sentinel-client/rest/remote/producer"; log.info("RestTemplate request url [{}] ",requestUrL); return restTemplate.getForObject(requestUrL, CommonResponse.class); } @GetMapping("/ignore-exception") @SentinelResource( value = "ignoreException", fallback = "ignoreExceptionFallback", fallbackClass = { MyFallbackHandler.class }, exceptionsToIgnore = { NullPointerException.class } ) public CommonResponse ignoreException(@RequestParam(defaultValue = "1") Integer code) { if (code % 2 == 0) { throw new NullPointerException("yout input code is: " + code); } else if ( code % 3 == 0){ throw new RuntimeException("yout input code is: " + code); } return CommonResponse.success(); } }
MyFallbackHandler
package cn.flowboot.e.commerce.fallback; import cn.flowboot.e.commerce.vo.CommonResponse; import lombok.extern.slf4j.Slf4j; @Slf4j public class MyFallbackHandler { public static CommonResponse remoteConsumerFallback() { log.error("remote consumer service fallback"); return CommonResponse.fail("fallback"); } public static CommonResponse ignoreExceptionFallback(Integer code) { log.error("ignore exception input code: [{}] has trigger exception", code); return CommonResponse.fail("ignoreExceptionFallback"); } }
配置统一处理异常
RestTemplateExceptionHandler
package cn.flowboot.e.commerce.conf; import cn.flowboot.e.commerce.vo.CommonResponse; import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse; import com.alibaba.csp.sentinel.slots.block.BlockException; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpRequest; import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpRequestExecution; @Slf4j public class RestTemplateExceptionHandler { public static SentinelClientHttpResponse handleBlock(HttpRequest request, byte[] body, ClientHttpRequestExecution execution,BlockException ex){ log.error("handler restTemplate block exception : [{}], [{}]", request.getURI().getPath(),request.getClass().getCanonicalName()); return new SentinelClientHttpResponse( JSON.toJSONString(CommonResponse.fail("服务限流",request.getClass().getCanonicalName())) ); } public static SentinelClientHttpResponse handleFallback(HttpRequest request, byte[] body, ClientHttpRequestExecution execution,BlockException ex){ log.error("handler restTemplate block exception : [{}], [{}]", request.getURI().getPath(),request.getClass().getCanonicalName()); return new SentinelClientHttpResponse( JSON.toJSONString(CommonResponse.fail("服务异常",request.getClass().getCanonicalName())) ); } }
SentinelConfig
package cn.flowboot.e.commerce.conf; import com.alibaba.cloud.sentinel.annotation.SentinelRestTemplate; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class SentinelConfig { @Bean @SentinelRestTemplate( fallback = "handleFallback",fallbackClass = RestTemplateExceptionHandler.class, blockHandler = "handleBlock",blockHandlerClass = RestTemplateExceptionHandler.class ) public RestTemplate restTemplate(){ return new RestTemplate(); } }
SentinelRestTemplateController 使用统一配置的RestTemplate
package cn.flowboot.e.commerce.controller; import cn.flowboot.e.commerce.block.handler.MyBlockHandler; import cn.flowboot.e.commerce.dto.SearchGoodByIdsDto; import cn.flowboot.e.commerce.vo.CommonResponse; import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.fastjson.JSON; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import java.util.HashMap; import java.util.List; import java.util.Map; @Slf4j @RequiredArgsConstructor @RestController @RequestMapping("/rest") public class SentinelRestTemplateController { private final RestTemplate restTemplate; @GetMapping("/remote/consumer") public CommonResponse remoteConsumer(){ String requestUrL = "http://localhost:8500/sentinel-client/rest/remote/producer"; log.info("RestTemplate request url [{}] ",requestUrL); return restTemplate.getForObject(requestUrL, CommonResponse.class); } @GetMapping("/remote/producer") public CommonResponse producer(){ log.info("coming in rate limit controller by resource"); return CommonResponse.success("producer"); } }
3.3 Feign 降级
@SentinelResource 中fallback、fallbackClass指定异常降级的类和方法Sentinel还对 Feign 实现了适配,支持Feign的容错降级
feign: sentinel: enabled: true
SentinelFeignController
package cn.flowboot.e.commerce.controller; import cn.flowboot.e.commerce.fallback.MyFallbackHandler; import cn.flowboot.e.commerce.feign.SentinelFeignClient; import cn.flowboot.e.commerce.vo.CommonResponse; import com.alibaba.csp.sentinel.annotation.SentinelResource; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import java.util.Map; @Slf4j @RequiredArgsConstructor @RestController @RequestMapping("/feign") public class SentinelFeignController { //注入普通 private final SentinelFeignClient sentinelFeignClient; @GetMapping("/remote/consumer") public CommonResponse remoteConsumer(){ log.info("Sentinel feign client request "); return sentinelFeignClient.producer(); } }
SentinelFeignClient 其中微服务定义不存在会抛出异常
package cn.flowboot.e.commerce.feign; import cn.flowboot.e.commerce.feign.fallback.SentinelFeignClientFallback; import cn.flowboot.e.commerce.vo.CommonResponse; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; @FeignClient( value = "e-commerce-sentinel-client-1", fallback = SentinelFeignClientFallback.class ) public interface SentinelFeignClient { @GetMapping("/sentinel-client/rest/remote/producer") CommonResponse producer(); }
SentinelFeignClientFallback Sentinel 对 OpenFeign 接口的降级策略
package cn.flowboot.e.commerce.feign.fallback; import cn.flowboot.e.commerce.feign.SentinelFeignClient; import cn.flowboot.e.commerce.vo.CommonResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @Slf4j @Component public class SentinelFeignClientFallback implements SentinelFeignClient { @Override public CommonResponse producer() { return CommonResponse.fail("服务错误"); } }
4 Sentinel 存储
4.1 SpringCloud Alibaba Sentinel 结合 Nacos
- Sentinel Dashboard将规则保存在内存中,重启之后就会丢失,所以,考虑使用外部持久化方案
- 在Nacos中创建规则,Nacos会推送到客户端
- Sentinel Dashboard也会从Nacos 去获取配置信息
- Sentinel存储在 Nacos 中的限流数据结构
需要添加依赖(上述新建项目依赖包含)
com.alibaba.csp sentinel-datasource-nacos
配置
spring: application: name: e-commerce-sentinel-client cloud: nacos: #服务发现 discovery: enabled: true server-addr: 127.0.0.1:8848 namespace: e-commerce-nacos-server metadata: management: context-path: ${server.servlet.context-path}/actuator sentinel: # 配置 sentinel dashboard 地址 transport: dashboard: 127.0.0.1:7777 port: 8719 # 会在应用对应的机器上启动一个 Http Server, 该 Server 会与 Sentinel 控制台做交互 datasource: # 名称任意, 代表数据源 ds: nacos: # NacosDataSourceProperties.java 中定义 server-addr: ${spring.cloud.nacos.discovery.server-addr} dataId: ${spring.application.name}-sentinel namespace: ${spring.cloud.nacos.discovery.namespace} groupId: DEFAULT_GROUP data-type: json # 规则类型: com.alibaba.cloud.sentinel.datasource.RuleType # FlowRule 就是限流规则 rule-type: flow # 服务启动直接建立心跳连接 eager: true # 开启或关闭 @SentinelRestTemplate resttemplate: sentinel: enabled: true feign: sentinel: enabled: true
nacos 中添加配置 e-commerce-sentinel-client-sentinel
[ { "resource": "byResource", "limitApp": "default", "grade": 1, "count": 5, "strategy": 0, "controlBehavior": 0, "clusterMode": false } ]
5 Gateway 结合 Sentinel
5.1 添加依赖
com.alibaba.cloud spring-cloud-starter-alibaba-sentinel com.alibaba.cloud spring-cloud-alibaba-sentinel-gateway com.alibaba.csp sentinel-datasource-nacos
5.2 硬编码配置
package cn.flowboot.e.commerce.config; import com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants; import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition; import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPathPredicateItem; import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPredicateItem; import com.alibaba.csp.sentinel.adapter.gateway.common.api.GatewayApiDefinitionManager; import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule; import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager; import com.alibaba.csp.sentinel.adapter.gateway.sc.SentinelGatewayFilter; import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler; import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager; import com.alibaba.csp.sentinel.adapter.gateway.sc.exception.SentinelGatewayBlockExceptionHandler; import com.alibaba.csp.sentinel.slots.block.RuleConstant; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.ObjectProvider; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.codec.ServerCodecConfigurer; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.reactive.result.view.ViewResolver; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import javax.annotation.PostConstruct; import java.util.*; @Slf4j @RequiredArgsConstructor @Configuration public class SentinelGatewayConfiguration { private final List viewResolvers; private final ServerCodecConfigurer serverCodecConfigurer; @Bean @Order(Ordered.HIGHEST_PRECEDENCE) public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() { // 默认会返回错误 message, code 429 return new SentinelGatewayBlockExceptionHandler( this.viewResolvers, this.serverCodecConfigurer ); } @Bean @Order(Ordered.HIGHEST_PRECEDENCE) public GlobalFilter sentinelGatewayFilter() { return new SentinelGatewayFilter(); } @PostConstruct public void doInit() { log.info("---------------------------------------------------"); // 加载网关限流规则 log.info("load sentinel gateway rules (code define)"); initGatewayRules(); // 加载自定义限流异常处理器 initBlockHandler(); log.info("---------------------------------------------------"); } private void initGatewayRules() { Set rules = new HashSet(); GatewayFlowRule rule = new GatewayFlowRule(); // 指定限流模式, 根据 route_id 做限流, 默认的模式 rule.setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_ROUTE_ID); // 指定 route_id -> service id rule.setResource("e-commerce-nacos-client"); // 按照 QPS 限流 rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 统计窗口和限流阈值 rule.setIntervalSec(3); rule.setCount(1); rules.add(rule); // 加载到网关中 GatewayRuleManager.loadRules(rules); } private void initBlockHandler() { // 自定义 BlockRequestHandler BlockRequestHandler blockRequestHandler = new BlockRequestHandler() { @Override public Mono handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) { log.error("------------- trigger gateway sentinel rule -------------"); Map result = new HashMap(); result.put("code", String.valueOf(HttpStatus.TOO_MANY_REQUESTS.value())); result.put("message", HttpStatus.TOO_MANY_REQUESTS.getReasonPhrase()); result.put("route", "e-commerce-nacos-client"); return ServerResponse .status(HttpStatus.TOO_MANY_REQUESTS) .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromValue(result)); } }; // 设置自定义限流异常处理器 GatewayCallbackManager.setBlockHandler(blockRequestHandler); } }
SentinelGatewayConfiguration 修改为api分组
public class SentinelGatewayConfiguration { // 相同代码略... private void initGatewayRules() { Set rules = new HashSet(); // GatewayFlowRule rule = new GatewayFlowRule(); // ... 注释之前单个规则 // rules.add(rule); // 限流分组, Sentinel 先去找规则定义, 再去找规则中定义的分组 rules.add( new GatewayFlowRule("nacos-client-api-1") .setCount(3).setIntervalSec(60) ); rules.add( new GatewayFlowRule("nacos-client-api-2") .setCount(1).setIntervalSec(60) ); // 加载到网关中 GatewayRuleManager.loadRules(rules); // 加载限流分组 initCustomizedApis(); } private void initCustomizedApis() { Set definitions = new HashSet(); // nacos-client-api 组, 最大的限制 ApiDefinition api = new ApiDefinition("nacos-client-api") .setPredicateItems(new HashSet() {{ // 模糊匹配 /ecommerce-nacos-client/ 及其子路径的所有请求 add(new ApiPathPredicateItem() .setPattern("/ecommerce-nacos-client/**") // 根据前缀匹配 .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX)); }}); // nacos-client-api-1 分组 ApiDefinition api1 = new ApiDefinition("nacos-client-api-1") .setPredicateItems(new HashSet() {{ add(new ApiPathPredicateItem() // 精确匹配 /n/service/instance/e-commerce-nacos-client .setPattern("/s/nacos-client/search/service/instance")); }}); // nacos-client-api-2 分组 ApiDefinition api2 = new ApiDefinition("nacos-client-api-2") .setPredicateItems(new HashSet() {{ add(new ApiPathPredicateItem() // 精确匹配 /imooc/ecommerce-nacos-client/nacos-client/project-config .setPattern("/ecommerce-nacos-client" + "/nacos-client/project-config")); }}); definitions.add(api1); definitions.add(api2); // 加载限流分组 GatewayApiDefinitionManager.loadApiDefinitions(definitions); } }
5.3 JSON文件配置方式
注释掉SentinelGatewayConfiguration中的@PostConstruct注解
在项目资源文件新建如下两个文件:
gateway-flow-rule-api-sentinel.json
[ { "apiName": "nacos-client-api", "predicateItems": [ { "pattern": "/s/nacos-client/search/service/instance" }, { "pattern": "/n/service/instance/**", "matchStrategy": 1 } ] } ]
gateway-flow-rule-sentinel.json
[ { "resource": "e-commerce-nacos-client", "resourceMode": 0, "count": 3, "intervalSec": 60 }, { "resource": "nacos-client-api", "resourceMode": 1, "count": 1, "intervalSec": 60 } ]
注意:maven clean 当前网关子项目,防止文件在target不存在
通过本地文件方式 配置
spring: cloud: sentinel: eager: true transport: port: 8720 dashboard: 127.0.0.1:7777 datasource: # 通过本地文件方式, 基于服务级别的配置 dsl.file: file: classpath:gateway-flow-rule-sentinel.json # 代表服务级别的限流, 一步步点进去看, 文件类型 ruleType: gw-flow # 通过本地文件方式, 细粒度对指定 api 进行配置 ds2.file: file: classpath:gateway-flow-rule-api-sentinel.json # 代表 API 分组, 一步步点进去看, 文件类型 ruleType: gw-api-group
5.3 Nacos存储配置方式
spring: cloud: sentinel: eager: true transport: port: 8720 dashboard: 127.0.0.1:7777 datasource: # 集成 Nacos ds1: nacos: server-addr: ${spring.cloud.nacos.discovery.server-addr} namespace: ${spring.cloud.nacos.discovery.namespace} # 测试时, 看看 Nacos 中修改是否能让 dashboard 生效, 就把第二个 count 也修改为 3 data-id: gateway-flow-rule-sentinel group-id: DEFAULT_GROUP data-type: json rule-type: gw-flow ds2: nacos: server-addr: ${spring.cloud.nacos.discovery.server-addr} namespace: ${spring.cloud.nacos.discovery.namespace} data-id: gateway-flow-rule-sentinel group-id: DEFAULT_GROUP data-type: json rule-type: gw-api-group
Nacos 配置添加
gateway-flow-rule-sentinel
[ { "resource": "e-commerce-nacos-client", "resourceMode": 0, "count": 3, "intervalSec": 60 }, { "resource": "nacos-client-api", "resourceMode": 1, "count": 1, "intervalSec": 60 } ]
gateway-flow-rule-api-sentinel
[ { "apiName": "nacos-client-api", "predicateItems": [ { "pattern": "/s/nacos-client/search/service/instance" }, { "pattern": "/n/service/instance/**", "matchStrategy": 1 } ] } ]
均为json,上述三种需要分开测试,还有其他存储方式
Spring Cloud Alibaba 学习笔记项目:Github,学习笔记,仅为组件学习,并没有完整案例项目