You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
spring-cloud-alibaba/spring-cloud-alibaba-examples/sentinel-example/README-zh.md

14 KiB

Spring Cloud Alibaba Sentinel Example

项目说明

本 Example 项目演示如何使用 spring-cloud-starter-alibaba-sentinel 完成 Spring Cloud 应用中的流量治理功能。

Sentinel 是阿里巴巴开源的分布式系统的流量防卫组件Sentinel 以流量作为切入点,从流量控制,熔断降级,系统负载保护等多个维度保护服务的稳定性。

Sentinel Example

在本 Example 项目中,主要演示 Sentinel 断路器,整合 Spring Cloud Gateway 和 OpenFeign、RestTemplate 以及 Webclient 的使用。

下载并启动 Sentinel Console

  1. 首先需要获取 Sentinel 控制台Sentinel Console 支持直接下载和源码构建两种方式

    1. 直接下载:下载 Sentinel 控制台
    2. 源码构建:进入 Sentinel Github 项目页面,将代码 clone 到本地自行编译打包,参考此文档
  2. 启动控制台,执行 Java 命令 java -jar sentinel-dashboard.jar 完成 Sentinel 控制台的启动。

    控制台默认的监听端口为 8080。Sentinel 控制台使用 Spring Boot 编程模型开发,如果需要指定其他端口,请使用 Spring Boot 容器配置的标准方式,详情请参考 Spring Boot 文档

Sentinel Core Example

在此 Example 模块中,主要演示如何使用 Sentinel 的基本功能完成 Spring Cloud 应用的流量管控。 在启动 Example 进行演示之前,先了解一下如何在 Spring Cloud 应用中接入 Sentinel 组件。

项目编写

注意:本文档只是为了便于理解接入方式。本示例代码中已经完成接入工作,您无需再进行修改。

  1. 首先,修改 pom.xml 文件,引入 Sentinel starter。

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    
  2. 接入限流埋点

    • HTTP 埋点 spring-cloud-starter-alibaba-sentinel 默认为所有的 HTTP 服务提供了限流埋点,如果只想对 HTTP 服务进行限流,那么只需要引入依赖,无需修改代码。

    • 自定义埋点 如果需要对某个特定的方法进行限流或降级,可以通过 @SentinelResource 注解来完成限流的埋点,示例代码如下:

      @SentinelResource("resource")
      public String hello() {
          return "Hello";
      }
      

    当然也可以通过原始的 SphU.entry(xxx) 方法进行埋点,可以参见 Sentinel 文档

  3. 配置限流规则

    Sentinel 提供了两种配置限流规则的方式:代码配置 和 控制台配置。本示例使用的方式为通过代码配置。

    1. 通过代码来实现限流规则的配置。一个简单的限流规则配置示例代码如下,更多限流规则配置详情请参考 Sentinel 文档

      List<FlowRule> rules = new ArrayList<FlowRule>();
      FlowRule rule = new FlowRule();
      rule.setResource(str);
      // set limit qps to 10
      rule.setCount(10);
      rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
      rule.setLimitApp("default");
      rules.add(rule);
      FlowRuleManager.loadRules(rules);
      
    2. 通过控制台进行限流规则配置请参考文章后面的图文说明。

应用启动

  1. 增加配置,在应用的 /src/main/resources/application.yml 中添加基本配置信息

    server:
      port: 18083
    
    spring:
      application:
        name: sentinel-core-example
    
      cloud:
        sentinel:
          transport:
            dashboard: localhost:8080
    
  2. 启动应用,支持 IDE 直接启动和编译打包后启动。

    1. IDE直接启动找到主类 SentinelCoreApplication,执行 main 方法启动应用。
    2. 打包编译后启动:首先执行 mvn clean package 将工程编译打包,然后执行 java -jar sentinel-core-example.jar 启动应用。

调用服务验证

使用 curl 命令分别调用两个 URL可以看到访问成功。

$ curl http://localhost:18083/test
Blocked by Sentinel (flow limiting)

$ curl http://localhost:18083/hello
Hello

配置限流规则并验证

  1. 访问 http://localhost:8080 页面,进行登陆,默认用户名和密码均为:sentinel

    可以在左侧看到 sentinel-core-example 应用已经注册到了控制台,单击 流控规则 ,可以看到目前的流控规则为空。

    注意:如果您在控制台没有找到应用,请调用一下进行了 Sentinel 埋点的 URL 或方法,因为 Sentinel 使用了 lazy load 策略。详细的排查过程请参见 Sentinel FAQ

image-20240428171413303
  1. 配置 URL 限流规则:点击新增流控规则,资源名填写需要限流的 URL 相对路径,单机阈值选择需要限流的阈值,点击新增进行确认。(为了便于演示效果,这里将值设置成了 1)。
image-20240428171245517
  1. 配置自定义限流规则:点击新增流控规则,资源名填写 @SentinelResource 注解 value 字段的值,单机阈值选择需要限流的阈值,点击新增进行确认。(为了便于演示效果,这里将值设置成了 1)。
image-20240428171608519
  1. 访问 URL当 QPS 超过 1 时,可以看到限流效果如下。

    image-20240428171907705

自定义限流处理逻辑

  • 默认限流异常处理

    URL 限流触发后默认处理逻辑是,直接返回 "Blocked by Sentinel (flow limiting)"。 如果需要自定义处理逻辑,实现的方式如下:

    public class CustomUrlBlockHandler implements UrlBlockHandler {
        @Override
        public void blocked(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException {
            // todo add your logic
        }
    }
    
    WebCallbackManager.setUrlBlockHandler(new CustomUrlBlockHandler());
    
  • 使用 @SentinelResource 注解下的限流异常处理

    如果需要自定义处理逻辑,填写 @SentinelResource 注解的 blockHandler 属性(针对所有类型的 BlockException,需自行判断)或 fallback 属性(针对熔断降级异常),注意对应方法的签名和位置有限制,详情见 Sentinel 注解支持文档。示例实现如下:

    public class TestService {
    
        // blockHandler 是位于 ExceptionUtil 类下的 handleException 静态方法,需符合对应的类型限制.
        @SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {ExceptionUtil.class})
        public void test() {
            System.out.println("Test");
        }
    
        // blockHandler 是位于当前类下的 exceptionHandler 方法,需符合对应的类型限制.
        @SentinelResource(value = "hello", blockHandler = "exceptionHandler")
        public String hello(long s) {
            return String.format("Hello at %d", s);
        }
    
        public String exceptionHandler(long s, BlockException ex) {
            // Do some log here.
            ex.printStackTrace();
            return "Oops, error occurred at " + s;
        }
    }
    
    public final class ExceptionUtil {
    
        public static void handleException(BlockException ex) {
            System.out.println("Oops: " + ex.getClass().getCanonicalName());
        }
    }
    

一个简单的 @SentinelResource 示例可以见 sentinel-demo-annotation-spring-aop

Sentinel Circuitbreaker Example

本 Example 主要演示 OpenFeign 整合 Sentinel 断路器的使用。

准备配置文件

  1. 添加配置到配置中心。dataId 为 sentinel-circuitbreaker-rules.yml

    feign:
      circuitbreaker:
        enabled: true # 开启 feign 断路器支持
      sentinel:
        default-rule: default # 默认规则名称
        rules:
          # 默认规则, 对所有 feign client 生效
          default:
            - grade: 2 # 根据异常数目降级
              count: 1
              timeWindow: 15 # 降级后到半开状态的时间
              statIntervalMs: 1000
              minRequestAmount: 1
          # 只对 feign client user 生效
          user:
            - grade: 2
              count: 1
              timeWindow: 15
              statIntervalMs: 1000
              minRequestAmount: 1
          # 只对 feign client user 的方法 feignMethod 生效
          # 括号里是参数类型, 多个逗号分割, 比如 user#method(boolean,String,Map)
          "[user#feignMethod(boolean)]":
            - grade: 2
              count: 1
              timeWindow: 10
              statIntervalMs: 1000
              minRequestAmount: 1
    

验证配置生效

启动项目主类 FeignCircuitBreakerApplication

验证默认 Feign client 生效

先访问 http://localhost/test/default/false 2 次 1秒内
再访问 http://localhost/test/default/true 断路器处于打开状态

验证指定 Feign client 生效

先访问 http://localhost/test/feign/false 2 次 1秒内
再访问 http://localhost/test/feign/true 断路器处于打开状态

验证 Feign client 指定方法生效

先访问 http://localhost/test/feignMethod/false 2次 1秒内
再访问 http://localhost/test/feignMethod/true 断路器处于打开状态

规则动态刷新

修改配置中心的规则, 再访问上述接口。

Sentinel OpenFeign Example

本 Example 演示 OpenFeing 与 Sentinel 的整合。Example 中使用 httpbin 充当后台 API 接口服务。

项目编写

注意:本项目中代码已经完成相对应的功能,不需要再进行任何修改。

项目支持两种启动方式:通过主类 OpenFeignApplication 启动和 Jar 包启动两种方式。

调用测试

项目启动完成之后,可以通过访问对应的 URL 访问,查看对应的 Sentinel 流控效果。

注意:项目中提供的 RestTemplate 和 Webclient Example 同理。

Endpoint 信息查看

Spring Boot 应用支持通过 Endpoint 来暴露相关信息,spring-cloud-starter-alibaba-sentinel 也支持这一点。

在使用之前需要在 Maven 中添加 spring-boot-starter-actuator依赖,并在配置中允许 Endpoints 的访问。

  • Spring Boot 1.x 中添加配置 management.security.enabled=false
  • Spring Boot 2.x 中添加配置 management.endpoints.web.exposure.include=*

Spring Boot 1.x 可以通过访问 http://127.0.0.1:18083/sentinel 来查看 Sentinel Endpoint 的信息。Spring Boot 2.x 可以通过访问 http://127.0.0.1:18083/actuator/sentinel 来访问。

查看实时监控

Sentinel 控制台支持实时监控查看,您可以通过 Sentinel 控制台查看各链路的请求的通过数和被限流数等信息。 其中 p_qps 为通过(pass) 流控的 QPSb_qps 为被限流 (block) 的 QPS。

ReadableDataSource 支持

Sentinel 内部提供了动态规则的扩展实现 ReadableDataSource

Sentinel starter 整合了目前存在的几类 ReadableDataSource。只需要在配置文件中进行相关配置即可在 Spring 容器中自动注册 DataSource。

比如要定义两个ReadableDataSource分别是 FileRefreshableDataSourceNacosDataSource,配置如下:

spring.cloud.sentinel.datasource.ds1.file.file=classpath: degraderule.json
spring.cloud.sentinel.datasource.ds1.file.data-type=json

spring.cloud.sentinel.datasource.ds2.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.ds2.nacos.dataId=sentinel
spring.cloud.sentinel.datasource.ds2.nacos.groupId=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds2.nacos.data-type=json

ds1ds2 表示ReadableDataSource的名称可随意编写。ds1ds2 后面的 filenacos 表示ReadableDataSource的类型。

目前支持file, nacos, zk, apolloredis 这5种类型。

其中nacoszkapolloredis 这4种类型的使用需要加上对应的依赖sentinel-datasource-nacos, sentinel-datasource-zookeeper, sentinel-datasource-apollo, sentinel-datasource-redis

ReadableDataSource 加载规则数据成功的时候,控制台会打印出相应的日志信息:

[Sentinel Starter] DataSource ds1-sentinel-file-datasource load 3 DegradeRule
[Sentinel Starter] DataSource ds2-sentinel-nacos-datasource load 2 FlowRule

More

Sentinel 是一款功能强大的中间件,从流量控制,熔断降级,系统负载保护等多个维度保护服务的稳定性。此 Demo 仅演示了 使用 Sentinel 作为限流工具的使用,更多 Sentinel 相关的信息,请参考 Sentinel 项目

如果您对 spring-cloud-starter-alibaba-sentinel 有任何建议或想法,欢迎在 issue 中或者通过其他社区渠道向我们提出。