Table of contents
1. Overview of SpringCloud Alibaba Sentinel and the construction of the console
1. Overview of Spring Cloud Alibaba Sentinel
2. Construction of Sentinel console
3. What capabilities does the SpringCloud Alibaba Sentinel console have?
2. The current limiting function of sentinel is used in the project
2. yml configuration (under spring:cloud)
3. Write the current limiting controller interface
4. Write custom general current limiting processing logic
3. Use sentinel to protect calls between RestTemplate services
1.1, yml configuration file configuration
3. Use Sentinel to protect calls between RestTemplate services
4. Use sentinel to support fegin fuse downgrade
3. Write Sentinel's downgrade strategy for OpenFeign interface
4. Write a controller test using fegin's fusing downgrade
5. Use sentinel to support RestTemplate fuse downgrade
2. Write a controller test to use RestTemplate's fuse degradation
5. Sentinel combines Nacos to realize the persistence of current limiting rules
1. Spring Cloud Alibaba Sentinel configuration information
2. Integrate nacos to realize the persistence of current limiting rules
2.2. Writing a current-limiting interface
2.3, yml configuration (under spring:cloud)
2.4. Write the configuration of the specified current-limiting interface on nacos
6. Gateway integrates Sentinel to realize gateway current limiting
2. Write the configuration file (under spring:cloud)
4.2, write routing rule grouping
4.3. Writing configuration files
5.1. Write routing rules on nacos
5.2. Write routing rule groups on nacos
5.3, write yml configuration file
1. Overview of SpringCloud Alibaba Sentinel and the construction of the console
1. Overview of Spring Cloud Alibaba Sentinel
2. Construction of Sentinel console
2.1. Download address
Releases · alibaba/Sentinel · GitHub
2.2, start sentinel
java -Dserver.port=7777 -Dcsp.sentinel.dashboard.server=localhost:77
77 -Dproject.name=zhangkechen-sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar
2.3, visit sentinel
Address: http://localhost:7777/
3. What capabilities does the SpringCloud Alibaba Sentinel console have?
2. The current limiting function of sentinel is used in the project
1. Add dependencies
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2. yml configuration (under spring:cloud)
sentinel:
# 配置 sentinel dashboard 地址
transport:
dashboard: 127.0.0.1:7777
port: 8719 # 会在应用对应的机器上启动一个 Http Server, 该 Server 会与 Sentinel 控制台做交互
# 服务启动直接建立心跳连接
eager: true
datasource:
3. Write the current limiting controller interface
/**
* <h1>基于 Sentinel 控制台配置流控规则</h1>
* Sentinel 是懒加载的, 先去访问一下, 就可以在 Sentinel Dashboard 看到了
* */
@Slf4j
@RestController
@RequestMapping("/dashboard")
public class RateLimitController {
/**
* <h2>在 dashboard 中 "流控规则" 中按照资源名称新增流控规则</h2>
* */
@GetMapping("/by-resource")
@SentinelResource(
value = "byResource",
blockHandler = "qinyiHandleBlockException",
blockHandlerClass = QinyiBlockHandler.class
)
public CommonResponse<String> byResource() {
log.info("coming in rate limit controller by resource");
return new CommonResponse<>(0, "", "byResource");
}
/**
* <h2>在 "簇点链路" 中给 url 添加流控规则</h2>
* */
@GetMapping("/by-url")
@SentinelResource(value = "byUrl")
public CommonResponse<String> byUrl() {
log.info("coming in rate limit controller by url");
return new CommonResponse<>(0, "", "byUrl");
}
}
4. Write custom general current limiting processing logic
/**
* <h1>自定义通用的限流处理逻辑</h1>
* */
@Slf4j
public class QinyiBlockHandler {
/**
* <h2>通用限流处理方法</h2>
* 这个方法必须是 static 的
* */
public static CommonResponse<String> qinyiHandleBlockException(BlockException exception) {
log.error("trigger qinyi block handler: [{}], [{}]",
JSON.toJSONString(exception.getRule()), exception.getRuleLimitApp());
return new CommonResponse<>(
-1,
"flow rule trigger block exception",
null
);
}
}
3. Use sentinel to protect calls between RestTemplate services
1, placement RestTemplate
1.1, yml configuration file configuration
# 开启或关闭 @SentinelRestTemplate 注解
resttemplate:
sentinel:
enabled: true
1.2, code configuration
/**
* <h1>开启服务间的调用保护, 需要给 RestTemplate 做一些包装</h1>
* */
@Slf4j
@Configuration
public class SentinelConfig {
/**
* <h2>包装 RestTemplate</h2>
* */
@Bean
@SentinelRestTemplate(
fallback = "handleFallback", fallbackClass = RestTemplateExceptionUtil.class,
blockHandler = "handleBlock", blockHandlerClass = RestTemplateExceptionUtil.class
)
public RestTemplate restTemplate() {
return new RestTemplate(); // 可以对其做一些业务相关的配置
}
}
2. Configure the processing method after the service is abnormally degraded and the processing method after the current limit
/**
* <h1>RestTemplate 在限流或异常时的兜底方法</h1>
* */
@Slf4j
public class RestTemplateExceptionUtil {
/**
* <h2>限流后的处理方法</h2>
* */
public static SentinelClientHttpResponse handleBlock(HttpRequest request,
byte[] body,
ClientHttpRequestExecution execution,
BlockException ex) {
log.error("Handle RestTemplate Block Exception: [{}], [{}]",
request.getURI().getPath(), ex.getClass().getCanonicalName());
return new SentinelClientHttpResponse(
JSON.toJSONString(new JwtToken("qinyi-imooc-block"))
);
}
/**
* <h2>异常降级之后的处理方法</h2>
* */
public static SentinelClientHttpResponse handleFallback(HttpRequest request,
byte[] body,
ClientHttpRequestExecution execution,
BlockException ex) {
log.error("Handle RestTemplate Fallback Exception: [{}], [{}]",
request.getURI().getPath(), ex.getClass().getCanonicalName());
return new SentinelClientHttpResponse(
JSON.toJSONString(new JwtToken("qinyi-imooc-block"))
);
}
}
3. Use Sentinel to protect calls between RestTemplate services
/**
* <h1>使用 Sentinel 保护 RestTemplate 服务间调用</h1>
* */
@Slf4j
@RestController
@RequestMapping("/sentinel-rest-template")
public class SentinelRestTemplateController {
private final RestTemplate restTemplate;
public SentinelRestTemplateController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
/**
* <h2>从授权服务中获取 JwtToken</h2>
* 1. 流控降级:
* 是针对于簇点链路中的 http://127.0.0.1:7000/ecommerce-authority-center/authority/token
* 2. 容错降级: 对于服务不可用时不能生效
* */
@PostMapping("/get-token")
public JwtToken getTokenFromAuthorityService(
@RequestBody UsernameAndPassword usernameAndPassword) {
String requestUrl =
"http://127.0.0.1:7000/ecommerce-authority-center/authority/token";
log.info("RestTemplate request url and body: [{}], [{}]",
requestUrl, JSON.toJSONString(usernameAndPassword));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return restTemplate.postForObject(
requestUrl,
new HttpEntity<>(JSON.toJSONString(usernameAndPassword), headers),
JwtToken.class
);
}
}
4. Use sentinel to support fegin fuse downgrade
1. Configure fegin
# 打开 Sentinel 对 Feign 的支持
feign:
sentinel:
enabled: true
2. Write fegin client
/**
* <h1>通过 Sentinel 对 OpenFeign 实现熔断降级</h1>
* */
@FeignClient(
value = "e-commerce-imooc",
fallback = SentinelFeignClientFallback.class
)
public interface SentinelFeignClient {
@RequestMapping(value = "qinyi", method = RequestMethod.GET)
CommonResponse<String> getResultByFeign(@RequestParam Integer code);
}
3. Write Sentinel's downgrade strategy for OpenFeign interface
/**
* <h1>Sentinel 对 OpenFeign 接口的降级策略</h1>
* */
@Slf4j
@Component
public class SentinelFeignClientFallback implements SentinelFeignClient {
@Override
public CommonResponse<String> getResultByFeign(Integer code) {
log.error("request supply for test has some error: [{}]", code);
return new CommonResponse<>(
-1,
"sentinel feign fallback",
"input code: "+ code
);
}
}
4. Write a controller test using fegin's fusing downgrade
/**
* <h1>OpenFeign 集成 Sentinel 实现熔断降级</h1>
* */
@Slf4j
@RestController
@RequestMapping("/sentinel-feign")
public class SentinelFeignController {
private final SentinelFeignClient sentinelFeignClient;
public SentinelFeignController(SentinelFeignClient sentinelFeignClient) {
this.sentinelFeignClient = sentinelFeignClient;
}
/**
* <h2>通过 Feign 接口去获取结果</h2>
* */
@GetMapping("/result-by-feign")
public CommonResponse<String> getResultByFeign(@RequestParam Integer code) {
log.info("coming in get result by feign: [{}]", code);
return sentinelFeignClient.getResultByFeign(code);
}
}
5. Use sentinel to support RestTemplate fuse downgrade
1. Write the strategy after the service fuse and downgrade (the method in the fallback in the controller and the method parameters in the class must be consistent)
/**
* <h1>Sentinel 回退降级的兜底策略</h1>
* 都需要是静态方法 fallback中的方法和类中的方法参数必须一致
* */
@Slf4j
public class QinyiFallbackHandler {
/**
* <h2>getTokenFromAuthorityService 方法的 fallback</h2>
* */
public static JwtToken getTokenFromAuthorityServiceFallback(
UsernameAndPassword usernameAndPassword
) {
log.error("get token from authority service fallback: [{}]",
JSON.toJSONString(usernameAndPassword));
return new JwtToken("imooc-qinyi-fallback");
}
/**
* <h2>ignoreException 方法的 fallback</h2>
* */
public static JwtToken ignoreExceptionFallback(Integer code) {
log.error("ignore exception input code: [{}] has trigger exception", code);
return new JwtToken("imooc-qinyi-fallback");
}
}
2. Write a controller test to use RestTemplate's fuse degradation
package com.imooc.ecommerce.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.fastjson.JSON;
import com.imooc.ecommerce.fallback_handler.QinyiFallbackHandler;
import com.imooc.ecommerce.vo.JwtToken;
import com.imooc.ecommerce.vo.UsernameAndPassword;
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.*;
import org.springframework.web.client.RestTemplate;
/**
* <h1>Sentinel 提供容错降级的功能 服务未启动(容错了)</h1>
* */
@SuppressWarnings("all")
@Slf4j
@RestController
@RequestMapping("/sentinel-fallback")
public class SentinelFallbackController {
/** 注入没有增强的 RestTemplate */
private final RestTemplate restTemplate;
public SentinelFallbackController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@PostMapping("/get-token")
@SentinelResource(
value = "getTokenFromAuthorityService",
fallback = "getTokenFromAuthorityServiceFallback",
fallbackClass = { QinyiFallbackHandler.class }
)
public JwtToken getTokenFromAuthorityService(
@RequestBody UsernameAndPassword usernameAndPassword) {
String requestUrl =
"http://127.0.0.1:7000/ecommerce-authority-center/authority/token";
log.info("RestTemplate request url and body: [{}], [{}]",
requestUrl, JSON.toJSONString(usernameAndPassword));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return restTemplate.postForObject(
requestUrl,
new HttpEntity<>(JSON.toJSONString(usernameAndPassword), headers),
JwtToken.class
);
}
/**
* <h2>让 Sentinel 忽略一些异常</h2>
* */
@GetMapping("/ignore-exception")
@SentinelResource(
value = "ignoreException",
fallback = "ignoreExceptionFallback",
fallbackClass = { QinyiFallbackHandler.class },
exceptionsToIgnore = { NullPointerException.class }
)
public JwtToken ignoreException(@RequestParam Integer code) {
if (code % 2 == 0) {
throw new NullPointerException("yout input code is: " + code);
}
return new JwtToken("qinyi-imooc");
}
}
5. Sentinel combines Nacos to realize the persistence of current limiting rules
1. Spring Cloud Alibaba Sentinel configuration information
2. Integrate nacos to realize the persistence of current limiting rules
2.1. Add dependencies
<!-- Sentinel 使用 Nacos 存储规则 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
2.2. Writing a current-limiting interface
/**
* <h2>在 dashboard 中 "流控规则" 中按照资源名称新增流控规则</h2>
* */
@GetMapping("/by-resource")
@SentinelResource(
value = "byResource",
blockHandler = "qinyiHandleBlockException",
blockHandlerClass = QinyiBlockHandler.class
)
public CommonResponse<String> byResource() {
log.info("coming in rate limit controller by resource");
return new CommonResponse<>(0, "", "byResource");
}
2.3, yml configuration (under spring:cloud)
sentinel:
# 配置 sentinel dashboard 地址
transport:
dashboard: 127.0.0.1:7777
port: 8719 # 会在应用对应的机器上启动一个 Http Server, 该 Server 会与 Sentinel 控制台做交互
# 服务启动直接建立心跳连接
eager: true
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
2.4. Write the configuration of the specified current-limiting interface on nacos
[
{
"resource": "byresource",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
6. Gateway integrates Sentinel to realize gateway current limiting (no matter which way the boilerplate code in hard coding must be added to Gateway)
1. Introduce dependencies
<!-- 集成 Sentinel, 在网关层面实现限流 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<!-- Sentinel 使用 Nacos 存储规则 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
2. Write the configuration file (under spring:cloud)
sentinel:
# 配置 sentinel dashboard 地址
transport:
dashboard: 127.0.0.1:7777
port: 8719 # 会在应用对应的机器上启动一个 Http Server, 该 Server 会与 Sentinel 控制台做交互
# 服务启动直接建立心跳连接
eager: true
3. Hard-coded way to achieve
package com.imooc.ecommerce.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.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.*;
/**
* <h1>Gateway 集成 Sentinel 实现限流</h1>
* */
@Slf4j
@Configuration
public class SentinelGatewayConfiguration {
//=====================================================样板间式代码开始=====================================================
/** 视图解析器 */
private final List<ViewResolver> viewResolvers;
/** HTTP 请求和响应数据的编解码配置 */
private final ServerCodecConfigurer serverCodecConfigurer;
/**
* <h2>构造方法</h2>
* */
public SentinelGatewayConfiguration(
ObjectProvider<List<ViewResolver>> viewResolversProvider,
ServerCodecConfigurer serverCodecConfigurer
) {
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
this.serverCodecConfigurer = serverCodecConfigurer;
}
/**
* <h2>限流异常处理器, 限流异常出现时, 执行到这个 handler</h2>
* */
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
// 默认会返回错误 message, code 429
return new SentinelGatewayBlockExceptionHandler(
this.viewResolvers,
this.serverCodecConfigurer
);
}
/**
* <h2>限流过滤器, 是 Gateway 全局过滤器, 优先级定义为最高</h2>
* */
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
/**
* 自定义限流异常返回
*/
@PostConstruct
public void initBlockHandlers() {
BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
Map result = new HashMap();
result.put("code","500016");
result.put("msg","接口被限流了");
return ServerResponse.status(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromObject(result));
}
};
GatewayCallbackManager.setBlockHandler(blockRequestHandler);
}
//=====================================================样板间式代码结束=====================================================
//=====================================================硬编码方式实现限流规则============================================//
/**
* <h2>初始化限流规则</h2>
* */
// @PostConstruct
public void doInit() {
log.info("---------------------------------------------------");
// 加载网关限流规则
log.info("load sentinel gateway rules (code define)");
initGatewayRules();
// 加载自定义限流异常处理器
initBlockHandler();
log.info("---------------------------------------------------");
}
/**
* <h2>硬编码网关限流规则</h2>
* */
private void initGatewayRules() {
Set<GatewayFlowRule> 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(60);
rule.setCount(3);
// 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();
}
/**
* <h2>自定义限流异常处理器</h2>
* */
private void initBlockHandler() {
// 自定义 BlockRequestHandler
BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange,
Throwable throwable) {
log.error("------------- trigger gateway sentinel rule -------------");
Map<String, String> 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);
}
/**
* <h2>硬编码网关限流分组</h2>
* 1. 最大限制 - 演示
* 2. 具体的分组
* */
private void initCustomizedApis() {
Set<ApiDefinition> definitions = new HashSet<>();
// nacos-client-api 组, 最大的限制
ApiDefinition api = new ApiDefinition("nacos-client-api")
.setPredicateItems(new HashSet<ApiPredicateItem>() {
{
// 模糊匹配 /imooc/ecommerce-nacos-client/ 及其子路径的所有请求
add(new ApiPathPredicateItem()
.setPattern("/imooc/ecommerce-nacos-client/**")
// 根据前缀匹配
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
// nacos-client-api-1 分组
ApiDefinition api1 = new ApiDefinition("nacos-client-api-1")
.setPredicateItems(new HashSet<ApiPredicateItem>() {
{
add(new ApiPathPredicateItem()
// 精确匹配 /imooc/ecommerce-nacos-client/nacos-client/service-instance
.setPattern("/imooc/ecommerce-nacos-client" +
"/nacos-client/service-instance"));
}});
// nacos-client-api-2 分组
ApiDefinition api2 = new ApiDefinition("nacos-client-api-2")
.setPredicateItems(new HashSet<ApiPredicateItem>() {
{
add(new ApiPathPredicateItem()
// 精确匹配 /imooc/ecommerce-nacos-client/nacos-client/project-config
.setPattern("/imooc/ecommerce-nacos-client" +
"/nacos-client/project-config"));
}});
definitions.add(api1);
definitions.add(api2);
// 加载限流分组
GatewayApiDefinitionManager.loadApiDefinitions(definitions);
}
}
4. Local file implementation
4.1. Writing routing rules
gateway-flow-rule-sentinel.json (routing rules, resource can be interface name, microservice name, group name, resourceMode=1, resourceMode=0 means grouping)
[
{
"resource": "e-commerce-nacos-client",
"resourceMode": 0,
"count": 3,
"intervalSec": 60
},
{
"resource": "nacos-client-api",
"resourceMode": 1,
"count": 1,
"intervalSec": 60
}
]
4.2, write routing rule grouping
gateway-flow-rule-api-sentinel.json (routing rule grouping, indicating that when the resource is apiname, the interface paths in the grouping follow the flow-limiting rules in the resource)
[
{
"apiName": "nacos-client-api",
"predicateItems": [
{
"pattern": "/imooc/ecommerce-nacos-client/nacos-client/project-config"
},
{
"pattern": "/imooc/ecommerce-nacos-client/**",
"matchStrategy": 1
}
]
}
]
4.3. Writing configuration files
sentinel:
eager: true
transport:
client-ip: 8720
dashboard: 127.0.0.1:7777
datasource:
dsl.file:
file: classpath:gateway-flow-rule-sentinel.json
ruleType: gw-flow
ds2.file:
file: classpath:gateway-flow-rule-api-sentinel.json
ruleType: gw-api-group
5. Nacos implementation
5.1. Write routing rules on nacos
gateway-flow-rule-sentinel.json (routing rules, resource can be interface name, microservice name, group name, resourceMode=0 is roteId, resourceMode=1 means api grouping)
[
{
"resource": "e-commerce-nacos-client",
"resourceMode": 0,
"count": 3,
"intervalSec": 60
},
{
"resource": "nacos-client-api",
"resourceMode": 1,
"count": 1,
"intervalSec": 60
}
]
5.2. Write routing rule groups on nacos
gateway-flow-rule-api-sentinel.json (routing rule grouping, indicating that when the resource is apiname, the interface path in the grouping is changed according to the current limiting rule in the resource, matchStrategy=1 means fuzzy matching, and the default is exact matching )
[
{
"apiName": "nacos-client-api",
"predicateItems": [
{
"pattern": "/imooc/ecommerce-nacos-client/nacos-client/project-config"
},
{
"pattern": "/imooc/ecommerce-nacos-client/**",
"matchStrategy": 1
}
]
}
]
5.3, write yml configuration file
sentinel:
eager: true
transport:
client-ip: 8720
dashboard: 127.0.0.1:7777
datasource:
# 名称任意, 代表数据源
ds1:
nacos:
# NacosDataSourceProperties.java 中定义
server-addr: ${spring.cloud.nacos.discovery.server-addr}
dataId: gateway-flow-rule-sentinel
namespace: ${spring.cloud.nacos.discovery.namespace}
groupId: DEFAULT_GROUP
data-type: json
# 规则类型: com.alibaba.cloud.sentinel.datasource.RuleType
# FlowRule 就是限流规则
rule-type: gw_flow
# 名称任意, 代表数据源
ds2:
nacos:
# NacosDataSourceProperties.java 中定义
server-addr: ${spring.cloud.nacos.discovery.server-addr}
dataId: gateway-flow-rule-api-sentinel
namespace: ${spring.cloud.nacos.discovery.namespace}
groupId: DEFAULT_GROUP
data-type: json
# 规则类型: com.alibaba.cloud.sentinel.datasource.RuleType
# FlowRule 就是限流规则
rule-type: gw_api_group