目前原生 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

准备工作

在开始开发前,请确保您已经完成以下工作:

  • 下载 Maven 并设置环境变量。
  • 下载最新版本的 Sentinel Dashboard
  • 在本地执行以下命令,启动 Sentinel Dashboard。

    java -Dserver.port=<ListenPort> -jar sentinel-dashboard-<Version>.jar

    • <ListenPort> 表示 sentinel dashboard 的监听端口,例如:8081(下方测试用例中使用的端口)
    • sentinel-dashboard-<Version>.jar 表示 sentinel dashboard 的 jar 包名称,例如:sentinel-dashboard-1.6.0.jar
  • 登录本地 Sentinel Dashboard 控制台 http://127.0.0.1<ListenPort>(例如:http://127.0.0.1:8081,用户名和密码同为 sentinel),新建限流规则。

使用 Sentinel 实现限流

  1. 实现限流。
    1. 创建命名为 sentinel-flow-example 的 Maven 工程,。
    2. 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 版本的生命周期已结束,不推荐使用这个版本开发应用。
    3. src\main\java 下创建 Package com.aliware.edas
    4. 在 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);
           }
       }                                
    5. 在 Packagecom.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 配置项。详情请参见注解支持
    6. 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                                
    7. 执行SentinelFlowExampleApplication中的 main 函数,启动应用。
  2. 新建流控规则。
    在本地 Sentinel Dashboard 中对 sentinel-flow-example 应用新建流控规则。
    1. 访问 http://127.0.0.1:8081, 进入 Sentinel 控制台。
      会看到运行的 sentinel-flow-example 应用。
    2. 在左侧导航栏单击该应用右侧的下拉箭头,并在菜单中单击流控规则
    3. 流控规则页面添加两个流控规则。
      • 资源名为/flow,来源应用会 default, 阈值类型是 QPS,单机阈值为 0。
      • 资源名为test,来源应用会 default, 阈值类型是 QPS,单机阈值为 0。
  3. 结果验证。
    • 在浏览器访问 http://localhost:18888/flow ,返回 Blocked by Sentinel (flow limiting),则表明该应用被成功限流。
    • 在浏览器访问 http://localhost:18888/save ,返回 block ,则表明该应用被成功限流。

使用 Sentinel 实现降级

  1. 实现降级。
    1. 创建命名为sentinel-degrade-example的 Maven 工程。
    2. 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 版本的生命周期已结束,不推荐使用这个版本开发应用。
    3. src\main\java 下创建 Package com.aliware.edas
    4. 在 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);
           }
       }                           
    5. 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             
    6. 执行SentinelDrgradeExampleApplication中的 main 函数,启动应用。
  2. 新建降级规则
    在本地 Sentinel Dashboard 中对sentinel-degrade-example应用新建降级规则。
    1. 访问http://127.0.0.1:8081,进入 Sentinel 控制台。
      会看到运行的sentinel-degrade-example应用。
    2. 在左侧导航栏单击该应用右侧的下拉箭头,并在菜单中单击降级规则
    3. 降级规则页面添加两个流控规则。
      • 资源名为/rt,降级策略是 RT,RT 阈值为 200(毫秒),时间窗口为 30(秒)
      • 资源名为/exception,降级策略是 异常比例, 异常比列阈值 0.5,阈值为 0.5,时间窗口为 30(秒)
  3. 结果验证。
    • 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 控制台上对规则的操作无法真正生效。
  1. 为应用 sentinel-flow-example 配置限流规则。
    1. 登录 EDAS 控制台。
    2. 在左侧导航栏中选择应用管理 > 应用列表
    3. 应用列表页面选择部署应用的地域和命名空间,并单击部署的应用 sentinel-flow-example。
    4. 在应用详情页左侧导航栏选择限流降级 > 流控规则
    5. 流控规则页面右上角单击新建流控规则
    6. 在新建流控规则页面设置流控规则参数,并单击新建
      • /flow 流控规则

      • test 规则

  2. 为应用 sentinel-degrade-example 配置降级规则。
    1. 登录 EDAS 控制台。
    2. 在左侧导航栏中选择应用管理 > 应用列表
    3. 在应用详情页左侧导航栏选择限流降级 > 流控规则
    4. 流控规则页面右上角单击新建流控规则
    5. 新建降级规则页面设置降级规则参数,并单击新建
      • rt 降级规则

      • /exception 规则

结果验证

  1. 部署完成后,查看日志,确认应用是否启动成功。
    详情请参见查看实例日志
  2. 查看 sentinel-flow-example 流控结果。
    1. 执行命令curl http://<应用实例 IP>:<服务端口>/flow,如curl http://192.168.0.34:9999/flow 查看是否返回Blocked by Sentinel (flow limiting)
    2. 执行命令curl http://<应用实例 IP>:<服务端口>/save,如curl http://192.168.0.34:9999/save查看是否返回block
      说明 实际的服务端口可以在应用详情页的基本信息页面查询。
  3. 查看 sentinel-degrade-example 降级结果。
    1. 执行脚本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 次)。

    2. 执行脚本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 次)。