Spring Cloud应用已经支持使用Sentinel实现限流降级功能,在您将实现了限流降级的Spring Cloud部署到EDAS后,EDAS集成的AHAS接口为您的应用提供限流降级能力。

使用限制

  • 如果你的应用开发完成后,要部署到EDAS的ECS集群,请确保您使用的是专业版或铂金版EDAS,详情请参见产品系列
  • 如果您的应用要部署到EDAS的K8s集群,则没有使用限制。EDAS的K8s集群集成了接入AHAS的入口,在创建或部署应用的时候打开AHAS开关即可。

背景信息

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),新建限流规则。
  • 可选:

    在本地开发应用时,可以使用Alibaba Cloud Toolkit插件实现本地应用和部署在EDAS中的应用的相互调用,即端云互联,而无需搭建VPN,帮助您提升开发效率。详情请参见端云互联简介

使用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。EDASSpringCloud应用开发限流降级新增流控规则
      • 资源名为test,来源应用会default, 阈值类型是QPS,单机阈值为0。EDASSpringCloud应用开发限流降级新增流控规则test
  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(秒)EDAS使用SpringCloud开发应用实现限流降级之新建留空规则
      • 资源名为/exception,降级策略是异常比例, 异常比列阈值0.5,阈值为0.5,时间窗口为30(秒)EDAS使用SpringCloud开发应用实现限流降级之新建留空规则
  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次)

      EDAS使用SpringCloud开发应用实现限流降级之RT验证
    • 异常比例验证

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

      EDAS使用SpringCloud开发应用实现限流降级之异常比例验证

    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流控规则

        EDAS使用SpringCloud开发应用实现限流降级之新建流控规则flow
      • test规则

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

        EDAS使用SpringCloud开发应用实现限流降级之rt降级
      • /exception规则

        EDAS使用SpringCloud开发应用实现限流降级之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次)。