目录
17-1 SpringCloud Alibaba Sentinel 概览及控制台搭建
- Sentinel 的概念
- Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助您保障微服务的稳定性
- Sentinel 的来历
- 2012年,Sentinel诞生,主要功能为了入口流量控制
- 2013-2017年,Sentinel 在阿里巴巴集团内部迅速发展,成为基础技术模块,覆盖了所有的核心场景
- 2018年,Sentinel 开源,并持续演进
- Sentinel 的基本概念
- 资源:可以是 Java 应用程序中的任何内容,例如:由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码
- 方法签名
- URL
- 服务名
- 规则:围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则;且所有的规则可以动态实时调整
- 资源:可以是 Java 应用程序中的任何内容,例如:由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码
- Sentinel 控制台
- Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能
- 获取并启动 Sentinel Dashboard(控制台)
- 下载控制台 JAR 包: https://github.com/alibaba/Sentinel/releases
- java -Dserver.port=7777 -Dcsp.sentinel.dashboard.server=localhost:7777 -Dproject.name=edcode-sentinel-dashboard -jar sentinel-dashboard-1.8.1.jar
- 从 Sentinel 1.6.0 起, Sentinel Dashboard 引入了基本的登录功能,默认的用户名密码都是 sentinel
- Sentinel 控制台有哪些能力
- 查看机器列表以及健康情况:收集 Sentinel 客户端发送的心跳包,用于判断机器是否在线
- 监控(单机和集群聚合):通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控
- 规则管理和推送:统一管理推送规则
17.2.1 基于硬编码应用Sentinel的限流功能
- SpringCloud Alibaba Sentinel 流量控制
- 服务端需要根据系统的处理能力对流量进行控制,Sentinel作为一个调配器,可以根据需要把随机的请求调整成合适的形状
- SpringCloud Alibaba Sentinel 流量控制方向
- 资源的调用关系,例如资源的调用链路,资源和资源之间的关系
- 运行指标,例如QPS(每一秒多少请求到达系统)、线程池、系统负载等
- 控制的效果,例如直接限流、冷启动、排队等
17.2.1.1 创建项目工程 - sca-commerce-sentinel-client
Maven 依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>sca-commerce</artifactId>
<groupId>com.edcode.commerce</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<artifactId>sca-commerce-sentinel-client</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<!-- 模块名及描述信息 -->
<name>sca-commerce-sentinel-client</name>
<description>Sentinel Client</description>
<dependencies>
<!-- 创建工程需要的两个依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- Sentinel 适配了 Feign, 可以实现服务间调用的保护 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- Sentinel 使用 Nacos 存储规则 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<!-- web 工程 -->
<dependency>
<groupId>com.edcode.commerce</groupId>
<artifactId>sca-commerce-mvc-config</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<!--
SpringBoot的Maven插件, 能够以Maven的方式为应用提供SpringBoot的支持,可以将
SpringBoot应用打包为可执行的jar或war文件, 然后以通常的方式运行SpringBoot应用
-->
<build>
<finalName>${artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
配置文件 - bootstrap.yml
server:
port: 8100
servlet:
context-path: /scacommerce-sentinel-client
spring:
application:
name: sca-commerce-sentinel-client # 应用名称也是构成 Nacos 配置管理 dataId 字段的一部分 (当 config.prefix 为空时)
cloud:
nacos:
# 服务注册发现
discovery:
enabled: true # 如果不想使用 Nacos 进行服务注册和发现, 设置为 false 即可
#server-addr: ${NACOS_ADDR:127.0.0.1}:8848
server-addr: ${NACOS_ADDR_1:127.0.0.1}:8848,${NACOS_ADDR_2:127.0.0.1}:8858,${NACOS_ADDR_3:127.0.0.1}:8868 # Nacos 服务器地址
namespace: ${NAMESPACE_ID:1adcfdd8-5763-4768-9a15-9c7157988950}
metadata:
management:
context-path: ${server.servlet.context-path}/actuator
sentinel:
# 配置 sentinel dashboard 地址
transport:
dashboard: ${SENTINEL_ADDR:127.0.0.1}:${SENTINEL_WEB_PORT:7777}
port: ${SENTINEL_PORT:8719} # 会在应用对应的机器上启动一个 Http Server, 该 Server 会与 Sentinel 控制台做交互
# 服务启动直接建立心跳连接
eager: true
redis:
database: 0
host: ${REDIS_HOST:localhost}
port: ${REDIS_PORT:6379}
timeout: 5000
# 暴露端点
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
启动类 - SentinelClientApplication
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class SentinelClientApplication {
public static void main(String[] args) {
SpringApplication.run(SentinelClientApplication.class, args);
}
}
17.2.1.2 流控规则硬编码
自定义通用的限流处理逻辑
@Slf4j
public class BlockHandler {
/**
* 需要静态方法,才能被调用
*/
public static CommonResponse<String> handleBlockException(BlockException exception) {
log.error("触发块处理程序: [{}], [{}]", JSON.toJSONString(exception.getRule()), exception.getRuleLimitApp());
return new CommonResponse<>(
-1,
"流规则触发块异常",
null
);
}
}
流控规则硬编码的 Controller
@Slf4j
@RestController
@RequestMapping("/code")
public class FlowRuleCodeController {
/**
* 初始化流控规则
*/
@PostConstruct
public void init() {
// 流控规则集合
List<FlowRule> flowRules = new ArrayList<>();
// 创建流控规则
FlowRule flowRule = new FlowRule();
// 设置流控规则 QPS, 限流阈值类型 (QPS(每秒请求数多少), 并发线程数)
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 流量控制手段
flowRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
// 设置受保护的资源
flowRule.setResource("flowRuleCode");
// 设置受保护的资源的阈值
flowRule.setCount(1);
flowRules.add(flowRule);
// 加载配置好的规则
FlowRuleManager.loadRules(flowRules);
}
/**
* 采用硬编码限流规则的 Controller 方法
*/
@GetMapping("/flow-rule")
// @SentinelResource(value = "flowRuleCode")
// @SentinelResource(value = "flowRuleCode", blockHandler = "handleException")
@SentinelResource(
value = "flowRuleCode", blockHandler = "handleBlockException",
blockHandlerClass = BlockHandler.class
)
public CommonResponse<String> flowRuleCode() {
log.info("request flowRuleCode");
return new CommonResponse<>(0, "", "edcode-sca-ecommerce");
}
/**
* 兜底策略
* 当限流异常抛出时, 指定调用的方法
* @param exception
* @return
*/
public CommonResponse<String> handleException(BlockException exception) {
log.error("has block exception: [{}]", JSON.toJSONString(exception.getRule()));
return new CommonResponse<>(
-1,
"flow rule exception",
exception.getClass().getCanonicalName()
);
}
}
HTTP 请求测试
### 硬编码的流控规则
GET 127.0.0.1:8100/scacommerce-sentinel-client/code/flow-rule
Content-Type: application/json
记得启动 Sentinel 服务
java -Dserver.port=7777 -Dcsp.sentinel.dashboard.server=192.168.3.250:7777 -Dproject.name=edcode-sentinel-dashboard -jar sentinel-dashboard-1.8.3.jar
17.4.1 基于Sentinel Dashboard配置工程流控规则
17.4.1.1 基于 Sentinel 控制台配置流控规则
@Slf4j
@RestController
@RequestMapping("/dashboard")
public class RateLimitController {
/**
* 在 dashboard 中 "流控规则" 中按照资源名称新增流控规则
*
* @return
*/
@GetMapping("/by-resource")
@SentinelResource(
value = "byResource",
blockHandler = "handleBlockException",
blockHandlerClass = BlockHandler.class
)
public CommonResponse<String> byResource() {
log.info("按资源进入速率限制控制器");
return new CommonResponse<>(0, "", "byResource");
}
/**
* 在 "簇点链路" 中给 url 添加流控规则
*
* @return
*/
@GetMapping("/by-url")
@SentinelResource(value = "byUrl")
public CommonResponse<String> byUrl() {
log.info("通过 url 进入速率限制控制器");
return new CommonResponse<>(0, "", "byUrl");
}
}
17.4.1.2 rate-limit.http
### 根据资源名称限流
GET 127.0.0.1:8100/scacommerce-sentinel-client/dashboard/by-resource
Content-Type: application/json
### 根据 URL 限流
GET 127.0.0.1:8100/scacommerce-sentinel-client/dashboard/by-url
Content-Type: application/json
Sentinel 是懒加载的, 先去请求一下这里接口, 就可以在 Sentinel Dashboard 看到了
17.4.1.3 Sentinel 控制台界面配置
【流控规则】模块进入
【簇点链路】模块进入
请求 rate-limit.http 里面的接口
17.5.1 Sentinel对服务调用的保护-RestTemplate篇
- SpringCloud Alibaba Sentinel 对降级功能的支持
- Sentinel 支持对 RestTemplate 服务调用进行保护,实现流控降级和异常降级
17.5.1.1 使用 Sentinel 保护 RestTemplate 服务间调用
bootstrap.yml 添加支持
# 开启或关闭 @SentinelRestTemplate 注解
resttemplate:
sentinel:
enabled: true
开启服务间的调用保护, 需要给 RestTemplate 做一些包装
@Slf4j
@Configuration
public class SentinelConfig {
/**
* 包装 RestTemplate
*/
@Bean
@SentinelRestTemplate(
fallback = "handleFallback", fallbackClass = RestTemplateExceptionUtil.class,
blockHandler = "handleBlock", blockHandlerClass = RestTemplateExceptionUtil.class
)
public RestTemplate restTemplate() {
// 可以对其做一些业务相关的配置
return new RestTemplate();
}
}
RestTemplate 在限流或异常时的兜底方法
@Slf4j
public class RestTemplateExceptionUtil {
/**
* 限流后的处理方法
*/
public static SentinelClientHttpResponse handleBlock(HttpRequest request,
byte[] body,
ClientHttpRequestExecution execution,
BlockException ex) {
log.error("处理 RestTemplate 异常: [{}], [{}]",
request.getURI().getPath(), ex.getClass().getCanonicalName());
return new SentinelClientHttpResponse(
JSON.toJSONString(new JwtToken("edcode-sca-block"))
);
}
/**
* 异常降级之后的处理方法
*/
public static SentinelClientHttpResponse handleFallback(HttpRequest request,
byte[] body,
ClientHttpRequestExecution execution,
BlockException ex) {
log.error("处理 RestTemplate 回退异常: [{}], [{}]",
request.getURI().getPath(), ex.getClass().getCanonicalName());
return new SentinelClientHttpResponse(
JSON.toJSONString(new JwtToken("edcode-sca-block"))
);
}
}
API
@Slf4j
@RestController
@RequestMapping("/sentinel-rest-template")
@RequiredArgsConstructor
public class SentinelRestTemplateController {
private final RestTemplate restTemplate;
/**
* 从授权服务中获取 JwtToken
* 1. 流控降级:
* 是针对于簇点链路中的 http://127.0.0.1:7000/scacommerce-authority-center/authority/token
* 2. 容错降级: 对于服务不可用时不能生效
* */
@PostMapping("/get-token")
public JwtToken getTokenFromAuthorityService(
@RequestBody UsernameAndPassword usernameAndPassword) {
String requestUrl = "http://127.0.0.1:7000/scacommerce-authority-center/authority/token";
log.info("RestTemplate 请求 url 和正文: [{}], [{}]", 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
);
}
}
sentinel-rest-template.http
### 获取 Token [Note: 需要启动 AuthorityCenterApplication 服务]
POST 127.0.0.1:8100/scacommerce-sentinel-client/sentinel-rest-template/get-token
Content-Type: application/json
{
"username": "eddie@qq.com",
"password": "25d55ad283aa400af464c76d713c07ad"
}
需要提前启动 - 授权微服务,才能请求成功
17.6.1 通过Sentinel实现对请求的熔断降级
- SpringCloud Alibaba Sentinel 对降级功能的支持
- @SentinelResource 中 fallback、fallbackClass 指定异常降级类和方法
- Sentinel 还对 Feign 实现适配,支持 Feign 的容错降级
17.6.1.1 @SentinelResource 中 fallback、fallbackClass 指定异常降级类和方法
bootstrap.yml
# 打开 Sentinel 对 Feign 的支持
feign:
sentinel:
enabled: true
SentinelConfig 屏蔽增强 @SentinelRestTemplate 部分
@Slf4j
@Configuration
public class SentinelConfig {
/**
* 包装 RestTemplate
*/
@Bean
// @SentinelRestTemplate(
// fallback = "handleFallback", fallbackClass = RestTemplateExceptionUtil.class,
// blockHandler = "handleBlock", blockHandlerClass = RestTemplateExceptionUtil.class
// )
public RestTemplate restTemplate() {
// 可以对其做一些业务相关的配置
return new RestTemplate();
}
}
SentinelFallbackController 提供容错降级的功能
@SuppressWarnings("all")
@Slf4j
@RestController
@RequestMapping("/sentinel-fallback")
@RequiredArgsConstructor
public class SentinelFallbackController {
/**
* 注入没有增强的 RestTemplate
*/
private final RestTemplate restTemplate;
/**
*
* @param usernameAndPassword
* @return
*/
@PostMapping("/get-token")
@SentinelResource(
value = "getTokenFromAuthorityService",
fallback = "getTokenFromAuthorityServiceFallback",
fallbackClass = { FallbackHandler.class }
)
public JwtToken getTokenFromAuthorityService(
@RequestBody UsernameAndPassword usernameAndPassword) {
String requestUrl =
"http://127.0.0.1:7000/scacommerce-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
);
}
/**
* 让 Sentinel 忽略一些异常
* @param code
* @return
*/
@GetMapping("/ignore-exception")
@SentinelResource(
value = "ignoreException",
fallback = "ignoreExceptionFallback",
fallbackClass = { FallbackHandler.class },
exceptionsToIgnore = { NullPointerException.class }
)
public JwtToken ignoreException(@RequestParam Integer code) {
if (code % 2 == 0) {
throw new NullPointerException("you input code is: " + code);
}
return new JwtToken("edcode-sca");
}
}
Sentinel 回退降级的兜底策略
@Slf4j
public class FallbackHandler {
/**
* getTokenFromAuthorityService 方法的 fallback
*
* @param usernameAndPassword
* @return
*/
public static JwtToken getTokenFromAuthorityServiceFallback(
UsernameAndPassword usernameAndPassword
) {
log.error("从授权服务回退获取令牌: [{}]",
JSON.toJSONString(usernameAndPassword));
return new JwtToken("sca-edcode-fallback");
}
/**
* ignoreException 方法的 fallback
*
* @param code
* @return
*/
public static JwtToken ignoreExceptionFallback(Integer code) {
log.error("忽略异常输入代码: [{}] 有触发异常", code);
return new JwtToken("edcode-sca-fallback");
}
}
sentinel-fallback.http
### 获取 token
POST 127.0.0.1:8100/scacommerce-sentinel-client/sentinel-fallback/get-token
Content-Type: application/json
{
"username": "eddie@qq.com",
"password": "25d55ad283aa400af464c76d713c07ad"
}
### 忽略异常
GET 127.0.0.1:8100/scacommerce-sentinel-client/sentinel-fallback/ignore-exception?code=2
Content-Type: application/json
17.8.1 Sentinel结合Nacos实现动态限流及限流规则持久化
- SpringCloud Alibaba Sentinel 整合 Nacos
- Sentinel Dashboard 将规则保存在内存中,重启之后就会丢失,所以,考虑使用外部持久化方案
- 在 Nacos 中创建规则,Nacos会推送到客户端
- Sentinel Dashboard 也会从 Nacos 去获取配置信息
- SpringCloud Alibaba Sentinel 配置信息
- Sentinel 存储在 Nacos 中的限流数据结构
17.8.1.1 Nacos 准备配置文件
sca-commerce-sentinel-client-sentinel
[
{
"resource": "byResource",
"limitApp": "default",
"grade": 1,
"count": 3,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
说明
[
{
"resource": "byResource", // 资源名:com.edcode.commerce.controller.RateLimitController#byResource
"limitApp": "default", // 流控针对来源
"grade": 1, // 0=并发线程数、1=QPS(常用)
"count": 1, // 限流的阈值,这里是一秒钟通过一个请求
"strategy": 0, // 0=直接、1=关联、2=链路
"controlBehavior": 0, // 0=快速失败、1=Warm Up 2=排队等待
"clusterMode": false // 是否集群
}
]
17.8.1.2 Maven 依赖
<!-- Sentinel 使用 Nacos 存储规则. -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
17.8.1.3 完整 Yaml
server:
port: 8100
servlet:
context-path: /scacommerce-sentinel-client
spring:
application:
name: sca-commerce-sentinel-client # 应用名称也是构成 Nacos 配置管理 dataId 字段的一部分 (当 config.prefix 为空时)
cloud:
nacos:
# 服务注册发现
discovery:
enabled: true # 如果不想使用 Nacos 进行服务注册和发现, 设置为 false 即可
#server-addr: ${NACOS_ADDR:127.0.0.1}:8848
server-addr: ${NACOS_ADDR_1:127.0.0.1}:8848,${NACOS_ADDR_2:127.0.0.1}:8858,${NACOS_ADDR_3:127.0.0.1}:8868 # Nacos 服务器地址
namespace: ${NAMESPACE_ID:1adcfdd8-5763-4768-9a15-9c7157988950}
metadata:
management:
context-path: ${server.servlet.context-path}/actuator
sentinel:
# 配置 sentinel dashboard 地址
transport:
dashboard: ${SENTINEL_ADDR:127.0.0.1}:${SENTINEL_WEB_PORT:7777}
port: ${SENTINEL_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
########################## 这里结束
redis:
database: 0
host: ${REDIS_HOST:localhost}
port: ${REDIS_PORT:6379}
timeout: 5000
# 暴露端点
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
# 开启或关闭 @SentinelRestTemplate 注解
resttemplate:
sentinel:
enabled: true
# 打开 Sentinel 对 Feign 的支持
feign:
sentinel:
enabled: true
17.8.1.4 请求测试
使用 rate-limit.http
### 根据资源名称限流
GET 127.0.0.1:8100/scacommerce-sentinel-client/dashboard/by-resource
Content-Type: application/json
17.8.1.5 通过 Nacos 动态修改限流的阈值
17.13.1 Gateway集成Sentinel实现网关限流之Nacos篇
- Gateway 集成 Nacos + Sentinel 实现网关动态限流
17.13.2 bootstrap.yml
server:
port: 9001
servlet:
context-path: /edcode
spring:
application:
name: sca-commerce-gateway
cloud:
nacos:
# 服务注册发现
discovery:
enabled: true # 如果不想使用 Nacos 进行服务注册和发现, 设置为 false 即可
#server-addr: ${NACOS_ADDR:127.0.0.1}:8848
server-addr: ${NACOS_ADDR_1:127.0.0.1}:8848,${NACOS_ADDR_2:127.0.0.1}:8858,${NACOS_ADDR_3:127.0.0.1}:8868 # Nacos 服务器地址
namespace: ${NAMESPACE_ID:1adcfdd8-5763-4768-9a15-9c7157988950}
metadata:
management:
context-path: ${server.servlet.context-path}/actuator
sentinel:
# 配置 sentinel dashboard 地址
transport:
dashboard: ${SENTINEL_ADDR:127.0.0.1}:${SENTINEL_WEB_PORT:7777}
port: ${SENTINEL_PORT:8719} # 会在应用对应的机器上启动一个 Http Server, 该 Server 会与 Sentinel 控制台做交互
# 服务启动直接建立心跳连接
eager: true
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:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
namespace: ${spring.cloud.nacos.discovery.namespace}
data-id: gateway-flow-rule-api-sentinel
group-id: DEFAULT_GROUP
data-type: json
rule-type: gw-api-group
# Sentinel 对 Spring Cloud Gateway 的专属配置项,对应 SentinelGatewayProperties 类
scg:
order: -2147483648 # 过滤器顺序,默认为 -2147483648 最高优先级
fallback:
mode: response # fallback 模式,目前有三种:response、redirect、空(可以实现对 fallback 的自定义处理逻辑)
response-status: 429 # 响应状态码,默认为 429
response-body: '{"code":429,"message":"你被限流鸟~"}' # 响应内容,默认为空
content-type: application/json # 内容类型,默认为 application/json
# redirect: https://www.baidu.com # 对应 redirect 模式的配置fallback配置
# 静态路由
# gateway:
# routes:
# - id: path_route # 路由的ID
# uri: 127.0.0.1:8080/user/{id} # 匹配后路由地址
# predicates: # 断言, 路径相匹配的进行路由
# - Path=/user/{id}
kafka:
bootstrap-servers: ${KAFKA_SERVER:127.0.0.1}:${KAFKA_PORT:9092}
producer:
retries: 3
consumer:
auto-offset-reset: latest
zipkin:
sender:
type: ${ZIPKIN_KAFKA_SENDER:web} # 默认是 web
base-url: http://${ZIPKIN_URL:localhost}:${ZIPKIN_PORT:9411}/
main:
allow-bean-definition-overriding: true # 因为将来会引入很多依赖, 难免有重名的 bean
redis:
database: 0
host: ${REDIS_HOST:localhost}
port: ${REDIS_PORT:6379}
timeout: 5000
# 暴露端点
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
# 网关配置类, 是网关的数据, GatewayConfig.java 读取的配置
nacos:
gateway:
route:
config:
data-id: sca-commerce-gateway-router
group: sca-commerce
17.13.2 配置放上 Nacos (限流、API分组)
gateway-flow-rule-api-sentinel.json
[
{
"apiName": "nacos-client-api",
"predicateItems": [
{
"pattern": "/edcode/scacommerce-nacos-client/nacos-client/project-config"
},
{
"pattern": "/edcode/scacommerce-nacos-client/**",
"matchStrategy": 1
}
]
}
]
没有 matchStrategy字段,默认:精确
gateway-flow-rule-sentinel.json
[
{
"resource": "sca-commerce-nacos-client",
"resourceMode": 0,
"count": 3,
"intervalSec": 60
},
{
"resource": "nacos-client-api",
"resourceMode": 1,
"count": 1,
"intervalSec": 60
}
]
17.13.3 添加 Maven 依赖
<!-- 集成 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>
17.13.3 nacos-client.http 请求测试
### 查询服务
GET http://127.0.0.1:9001/edcode/scacommerce-nacos-client/nacos-client/service-instance?serviceId=sca-commerce-gateway
Accept: application/json
sca-commerce-user: eyJhbGciOiJSUzI1NiJ9.eyJzY2EtY29tbWVyY2UtdXNlciI6IntcImlkXCI6MTEsXCJ1c2VybmFtZVwiOlwiZWRkaWVAcXEuY29tXCJ9IiwianRpIjoiNjg0ZWRkZmQtNWZmMC00OTJlLWI1M2ItYTlmY2MzZDQzYmU3IiwiZXhwIjoxNjQxNjU3NjAwfQ.eRCnSn9eKPyMN8O1Sky5jGizdnv96xtuo8evOHKwytIrz6aYBAyrGuAnTdDIG7EOdU0wPUom-uU52sPaLAVw0LPbfefGrbKqsuVIsNG2IOiwkwl_fqLm6IxSC8jDEFTTCNH6-01WJ2gKZ2LrRn_ZGizQ3w0Y30KL6mK2vpx31Nb6kf_fospqL1iW7VoQQWgiY9tBQ790M4fMT9IcpEzWD6-w0j4_9nWlArEotrHMb5_FCBzqRBx6v0rQQcNwa667zFfZqn2UOw25Ajz859DmTagvjxPaFVJNwF3udsIIxLGQalE8E3-lDrqAoR-29Apf5uHINHSezqEY6PCmBP8tXg
token: edcode ## HeaderTokenGatewayFilter
按上面 /edcode/scacommerce-nacos-client/** 规则,请求一次之后需要等待 60秒,才能下一次请求
从而达到按照不同的 API接口,或者 通配符来完成 API接口的限流
17.13.4 问题综合
Sentinel 控制台不显示API管理规则
场景1:使用 rule-type: flow 配置是可以显示的,但是换成 rule-type: gw-flow 就不显示了
解决办法:
网关需要设置 -Dcsp.sentinel.app.type=1
sentinel-dashboard 启动也需要添加 -Dcsp.sentinel.app.type=1
[eddie@zk1 opt]# java -Dcsp.sentinel.app.type=1 -Dserver.port=7777 -Dcsp.sentinel.dashboard.server=192.168.3.250:7777 -Dproject.name=edcode-sentinel-dashboard -jar /opt/sentinel-dashboard-1.8.3.jar
请求链路 - 效果图
API 分组管理 - 效果图
参考:https://blog.csdn.net/qq_43437874/article/details/119992770