目前原生 Spring Cloud 应用已经支持使用 Sentinel 实现限流降级功能。
前提条件
请确保您使用的是专业版或铂金版 EDAS,详情请参见
产品系列。
背景信息
Sentinel 目前支持 WebServlet、RestTemplate 和 Feign。Zuul 和 Spring Cloud Gateway 需要 Spring
Cloud Alibaba 发布新版本后才支持,或者您可以参考 网关限流 自行进行 Bean 的设置。
说明 Sentinel 1.6 版本才开始支持网关限流。
限流降级所使用的基础框架是开源项目 Sentinel。
本地开发中主要描述开发中涉及的关键信息,如果您想了解完整的 Spring Cloud 程序,可下载 sentinel-flow-example 以及 sentinel-degrade-example。
准备工作
在开始开发前,请确保您已经完成以下工作:
使用 Sentinel 实现限流
- 实现限流。
- 创建命名为 sentinel-flow-example 的 Maven 工程,。
- 在
pom.xml
文件中添加依赖。
以 Spring Boot 2.1.4.RELEASE 和 Spring Cloud Greenwich.SR1 为例,依赖如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
示例中使用的版本为 Spring Cloud Greenwich ,对应 Spring Cloud Alibaba 版本为 2.1.1.RELEASE。
- 如果使用 Spring Cloud Finchley 版本,对应 Spring Cloud Alibaba 版本为 2.0.1.RELEASE。
- 如果使用 Spring Cloud Edgware 版本,对应 Spring Cloud Alibaba 版本为 1.5.1.RELEASE。
说明 Spring Cloud Edgware 版本的生命周期已结束,不推荐使用这个版本开发应用。
- 在
src\main\java
下创建 Package com.aliware.edas
。
- 在 Package
com.aliware.edas
中创建 sentinel-flow-example
的启动类 SentinelFlowExampleApplication
。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SentinelFlowExampleApplication {
public static void main(String[] args) {
SpringApplication.run(SentinelFlowExampleApplication.class, args);
}
}
- 在 Package
com.aliware.edas
中创建一个简单的 ControllerSentinelFlowController
,并暴露一些方法。
@RestController
public class SentinelFlowController {
@GetMapping("/flow")
public String flow() {
return "success";
}
@GetMapping("/save")
@SentinelResource(value = "test", blockHandler = "block")
public String save() {
return "test";
}
public String block(BlockException e) {
return "block";
}
}
说明 @SentinelResource
用于定义资源,并提供可选的异常处理和 fallback 配置项。详情请参见
注解支持。
- 在
src\main\resources
路径下创建文件application.properties
,在application.properties
中添加如下配置,指定 Sentinel Dashboard 的地址。
其中 127.0.0.1:8081 为 Sentinel Dashboard 的地址,如果您的 Sentinel Dashboard 部署在另外一台机器,则需要修改成对应的 IP 和端口。如果有其它需求,可以参考配置项参考在application.properties
文件中增加配置。
spring.application.name=sentinel-flow-example
server.port=18888
spring.cloud.sentinel.eager=true
spring.cloud.sentinel.transport.dashboard=127.0.0.1:8081
- 执行
SentinelFlowExampleApplication
中的 main 函数,启动应用。
- 新建流控规则。
在本地 Sentinel Dashboard 中对 sentinel-flow-example 应用新建流控规则。
- 访问 http://127.0.0.1:8081, 进入 Sentinel 控制台。
会看到运行的 sentinel-flow-example 应用。
- 在左侧导航栏单击该应用右侧的下拉箭头,并在菜单中单击流控规则。
- 在流控规则页面添加两个流控规则。
- 资源名为
/flow
,来源应用会 default, 阈值类型是 QPS,单机阈值为 0。
- 资源名为
test
,来源应用会 default, 阈值类型是 QPS,单机阈值为 0。
- 结果验证。
- 在浏览器访问 http://localhost:18888/flow ,返回
Blocked by Sentinel (flow limiting)
,则表明该应用被成功限流。
- 在浏览器访问 http://localhost:18888/save ,返回
block
,则表明该应用被成功限流。
使用 Sentinel 实现降级
- 实现降级。
- 创建命名为
sentinel-degrade-example
的 Maven 工程。
- 在
pom.xml
文件中添加依赖。
以 Spring Boot 2.1.4.RELEASE 和 Spring Cloud Greenwich.SR1 为例,依赖如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
示例中使用的版本为 Spring Cloud Greenwich ,对应 Spring Cloud Alibaba 版本为 2.1.1.RELEASE。
- 如果使用 Spring Cloud Finchley 版本,对应 Spring Cloud Alibaba 版本为 2.0.1.RELEASE。
- 如果使用 Spring Cloud Edgware 版本,对应 Spring Cloud Alibaba 版本为 1.5.1.RELEASE。
说明 Spring Cloud Edgware 版本的生命周期已结束,不推荐使用这个版本开发应用。
- 在
src\main\java
下创建 Package com.aliware.edas
。
- 在 Package
com.aliware.edas
中创建 sentinel-degrade-example
的启动类 SentinelDegradeExampleApplication
。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SentinelDegradeExampleApplication {
public static void main(String[] args) {
SpringApplication.run(SentinelDegradeExampleApplication.class, args);
}
}
- 在src\main\resources路径下创建文件application.properties,在
application.properties
中添加如下配置,指定 Sentinel Dashboard 的地址。
其中 127.0.0.1:8081 为 Sentinel Dashboard 的地址,如果您的 Sentinel Dashboard 部署在另外一台机器,则需要修改成对应的 IP 和端口。如果有其它需求,可以参考配置项参考在application.properties文件中增加配置。
spring.application.name=sentinel-degrade-example
server.port=19999
spring.cloud.sentinel.eager=true
spring.cloud.sentinel.transport.dashboard=127.0.0.1:8081
- 执行
SentinelDrgradeExampleApplication
中的 main 函数,启动应用。
- 新建降级规则
在本地 Sentinel Dashboard 中对sentinel-degrade-example
应用新建降级规则。
- 访问http://127.0.0.1:8081,进入 Sentinel 控制台。
会看到运行的sentinel-degrade-example
应用。
- 在左侧导航栏单击该应用右侧的下拉箭头,并在菜单中单击降级规则。
- 在降级规则页面添加两个流控规则。
- 资源名为
/rt
,降级策略是 RT,RT 阈值为 200(毫秒),时间窗口为 30(秒)。
- 资源名为
/exception
,降级策略是 异常比例, 异常比列阈值 0.5,阈值为 0.5,时间窗口为 30(秒)。
- 结果验证。
- RT 验证
执行脚本 rt.sh
#!/usr/bin/env bash
n=1
while [ $n -le 10 ]
do
echo `curl -s http://localhost:19999/rt`
let n++
done
执行 5 次后,接口被降级(降级至少要发生 5 次)
- 异常比例验证
执行脚本 exception.sh
#!/usr/bin/env bash
n=1
while [ $n -le 10 ]
do
echo `curl -s http://localhost:19999/exception`
let n++
done
执行 5 次后,接口被降级(降级至少要发生 5 次)
Spring Cloud Alibaba Sentinel Starter 提供了对 RestTemplate 的支持(构造 RestTemplate 的时候需要加上@SentinelRestTemplate
注解):
@Bean
@SentinelRestTemplate
public RestTemplate restTemplate() {
return new RestTemplate();
}
具体内容请参见 Sentinel 支持 RestTemplate。
Feign 的内容请参见 Sentinel 支持 Feign。
将应用部署到 EDAS
当在本地完成应用的开发和测试后,便可将应用程序打包并部署到 EDAS。您可以根据您的实际情况选择将 Spring Cloud 应用可以部署到 ECS 集群或容器服务
Kubernetes集群。部署应用的详细步骤请参见应用部署概述(ECS 集群)和应用部署概述(K8s 集群)。
EDAS 配置管理中心提供了正式商用版本 Sentinel Dashboard Server。您只需添加如下依赖即可:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>spring-boot-starter-ahas-sentinel-client</artifactId>
<version>1.2.1</version>
</dependency>
注意 如果要部署到 EDAS 上spring-boot-starter-ahas-sentinel-client
依赖必须要引入,否则在 EDAS 控制台上对规则的操作无法真正生效。
- 为应用 sentinel-flow-example 配置限流规则。
- 登录 EDAS 控制台。
- 在左侧导航栏中选择应用管理 > 应用列表。
- 在应用列表页面选择部署应用的地域和命名空间,并单击部署的应用 sentinel-flow-example。
- 在应用详情页左侧导航栏选择 。
- 在流控规则页面右上角单击新建流控规则。
- 在新建流控规则页面设置流控规则参数,并单击新建。
- 为应用 sentinel-degrade-example 配置降级规则。
- 登录 EDAS 控制台。
- 在左侧导航栏中选择应用管理 > 应用列表。
- 在应用详情页左侧导航栏选择 。
- 在流控规则页面右上角单击新建流控规则。
- 在新建降级规则页面设置降级规则参数,并单击新建。
结果验证
- 部署完成后,查看日志,确认应用是否启动成功。
- 查看 sentinel-flow-example 流控结果。
- 执行命令
curl http://<应用实例 IP>:<服务端口>/flow
,如curl http://192.168.0.34:9999/flow
查看是否返回Blocked by Sentinel (flow limiting)
- 执行命令
curl http://<应用实例 IP>:<服务端口>/save
,如curl http://192.168.0.34:9999/save
查看是否返回block
说明 实际的服务端口可以在应用详情页的基本信息页面查询。
- 查看 sentinel-degrade-example 降级结果。
- 执行脚本
rt.sh
。
假设 IP 是 192.168.0.34, 服务端口是 9999。
说明 实际的服务端口可以在应用详情页的基本信息页面查询。
#!/usr/bin/env bash
n=1
while [ $n -le 10 ]
do
echo `curl -s http://192.168.0.34:9999/rt`
let n++
done
看执行 5 次后,接口是否被降级(降级至少要发生 5 次)。
- 执行脚本
exception.sh
。
假设 ip 是 192.168.0.34, 服务端口是 9999。
说明 实际的服务端口可以在应用详情页的基本信息页面查询。
#!/usr/bin/env bash
n=1
while [ $n -le 10 ]
do
echo `curl -s http://192.168.0.34:9999/exception`
let n++
done
看执行 5 次后,接口是否被降级(降级至少要发生 5 次)。