Spring Cloud Ailibaba Sentinel
文章目录
1、Sentinel
- 您服务的流量哨兵。
 - 随着分布式系统变得越来越流行,服务之间的可靠性变得比以往任何时候都更加重要。Sentinel是一个强大的流量控制组件,以“流”为突破口,涵盖流控制、并发限制、断路、自适应系统保护等多个领域,保证微服务的可靠性。
 - Sentinel 保护资源的方式由规则定义,例如流控制、并发和断路规则。规则可以动态更改,并实时生效。
 - 提供了web界面,我们只需在一个前端页面完成相关的配置。
 - 与hystrix相似,但Sentinel的功能更强大更加的简便。
 - **官网:**https://github.com/alibaba/Sentinel/wiki
 
1、Sentinel的开源生态:

2、核心功能作用:
- 服务降级
 - 服务熔断
 - 流量控制
 
3、Sentinel分为两个部分:
- 核心库不依赖于任何框架或者库,能够运行与所有的java运行时环境,同时对dubbo、Spring Cloud等框架也有就好的支持。
 - 控制台(Dashboard)基于spring boot开发,打成jar包后直接运行
 - **下载地址:**https://github.com/alibaba/Sentinel/releases
 - 在下载的文件夹下面执行java -jar sentinel-dashboard-1.8.3.jar启动Sentinel
 - 访问:http://localhost:8080/ 【默认端口号为8080】
 


这样Sentinel环境搭建完成
2、Sentinel相关配置
- 方便管理包新建一个父工程
 - 父工程pom.xml
 
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.6.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2021.0.1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2021.0.1.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
 
- 创建一个子工程
 

- pom.xml
 
<dependencies>
    <!--nacos服务发现-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
        <version>2.2.0.RELEASE</version>
    </dependency>
    <!--nacos配置中心-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-nacos-config</artifactId>
        <version>2.2.0.RELEASE</version>
    </dependency>
    <!--sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
    <!--web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--图形化处理-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
        <version>2.6.5</version>
    </dependency>
    <!--lombok-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
 
- yaml
 
server:
  port: 8401  #端口号
spring:
  application:
    name: cloudalibaba-sentinel-service  #服务名
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848  #注册到nacos
    sentinel:
      transport:
        dashboard: localhost:8080  #让sentinel监控
        port: 8719
        
management:    #暴露监控
  endpoints:
    web:
      exposure:
        include: '*'
 
- 主启动类
 
package com.qiumin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class SentinelApplication8401 {
    public static void main(String[] args) {
        SpringApplication.run(SentinelApplication8401.class,args);
    }
}
 
- 启动nacos、启动Sentinel、启动该服务进行相关测试测试
 - 注意:我们需要访问服务一次才会被Sentinel监控到
 
2.1 流控规则
- controller
 
package com.qiumin.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class SentinelTestController {
    @GetMapping("/testA")
    public String TestA(){
        return Thread.currentThread().getName()+"\t"+"测试流量控制Qps"+"成功!!!";
    }
    @GetMapping("/testB")
    public String TestB(){
        return Thread.currentThread().getName()+"\t"+"测试流量控制Qps"+"成功!!!";
    }
}
 
- 访问我们的服务一次后,刷新Sentinel
 - http://localhost:8401/testA
 - http://localhost:8401/testB
 


- 为 /testA请求加上以上流量控制后,我们在访问http://localhost:8401/testA
 - 发现当我们大于一秒的时间去访问时正常访问,而小于一秒内点击都次就会提示我们限流了
 

流控搭配的策略有很多种
QPS:当每秒请求数达到阈值时限流
- 流控模式 
  
- 直接:api达到限流条件时直接限流。
 - 关联:当关联的资源达到阈值时就限流自己,【如:当支付服务达到阈值时,下单服务就要限流,保证支付模块压力较小】。
 - 链路:只记录链路上的流量(指定资源从入口资源进来的流量如果达到阈值,就执行限流)。
 
 - 流控效果块【只有QPS下才有流控效果,线程下限流没有】 
  
- 快速失败:直接限流。
 - Warm Up:根据codeFactor(冷加载因子,默认为3,阈值/冷加载因子=实际初始阈值,经过预热时长才到达我们设置的阈值。
 - 排队效果:均匀排队,请求可以过来,但一次只处理一个请求,没有处理的请求进行排队等。【漏桶算法】
 
 
线程数:当调用api的线程数达到阈值时限流
- 流控模式 
  
- 直接:api达到限流条件时直接限流。
 - 关联:当关联的资源达到阈值时就限流自己,【如:当支付服务达到阈值时,下单服务就要限流,保证支付模块压力较小】。
 - 链路:只记录链路上的流量(指定资源从入口资源进来的流量如果达到阈值,就执行限流)。
 
 - 没有流控效果
 
2.2 QPS+关联+快速失败

- 使用postman工具以每秒10次请求发送到**/testB**,由于大于设置阈值1,所以这是**/testA自己就限流**
 
2.3 QPS+直接+Warm Up

该策略下,我们刚开始时每秒访问不能超过3次,超过时限流,5s后阈值就到达10次,超过10次时限流
应用场景秒杀时先预热
2.4 线程数+直接

其他就不一一展示
特别注意:在sentinel添加的流控规则如果我们没有另外的操作,这些流控规则是临时的,即没有持久化,我们重启微服务后流控规则就会丢失,需要重新配置,后续我们会进行持久化,利用nacos
3、熔断降级
降级策略
- **RT【平均响应时间,秒】:**必须满足两个条件 
时间窗口内请求数大于5且平均响应时间超出阈值【注意如果请求数少于5时,程序有错时会直接报错,因为不满足两个服务降级条件,这只时运行时异常】 RT最大为5s(更大时需要自行设置)。 - **异常比例【秒】:**错误请求占全部请求的比例超过阈值时,降级。
 - **异常数【分钟】:**60s内的错误请求数量大于阈值降级。
 

4、热点key限流
底层就是 try-catch-finally
注意要使用热点限流功能需要有兜底的方法,且加上@SentinelResource注解
- controller
 
 @GetMapping("/testHotKey")
    @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")
    public String testHotKey(@RequestParam(value = "q1",required = false) String q1,
                             @RequestParam(value = "q2",required = false) String q2 ){
        return Thread.currentThread().getName()+"\t"+"测试HotKey成功!!!";
    }
    public String deal_testHotKey(String q1, String q2, BlockException exception){
        return "deal_testHotKey 热点key 限流";
    }
 
- 配置
 

- 例外向:即限流参数带了一个特殊值,带有该值的就不限流,其他的限流
 

5、系统规则

6、SentinelResource
- MyBlockHandler.java
 
package com.qiumin.myhandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
public class MyBlockHandler {
    public static String handler1(BlockException exception){
        return "兜底方法=======1!!!";
    }
    public static String handler2(BlockException exception){
        return "兜底方法=======2!!!";
    }
}
 
注意方法需为static,后面才调用得到
- controller
 
 @GetMapping("/test")
    @SentinelResource(value = "test",blockHandlerClass = MyBlockHandler.class, blockHandler = "handler2")  
    public String test(){
        return "okok";
    }
 
- blockHandlerClass: 利用该属性指定我们写的类。
 - **blockHandler:**利用该属性指定我们写的类中的哪个兜底方法。
 - @SentinelResource不支持private方法
 
7、熔断降级深理解
7.1 同时配置fallback和流控
- 父工程pom
 
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.6.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2021.0.1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2021.0.1.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
 
- 创建子工程 cloudalibaba-sentinel8401
 

- pom
 
<?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>springcloud2022</artifactId>
        <groupId>com.qiu</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cloudalibaba-sentinel-service8401</artifactId>
    <properties>
        <maven.compiler.source>15</maven.compiler.source>
        <maven.compiler.target>15</maven.compiler.target>
    </properties>
    <dependencies>
        <!--nacos服务发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>
        <!--nacos配置中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-nacos-config</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>
        <!--sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--图形化处理-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <version>2.6.5</version>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version>2.6.5</version>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
 
- yaml
 
server:
  port: 8401
spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719
management:
  endpoints:
    web:
      exposure:
        include: '*'
 
- 主启动类
 
package com.qiumin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class SentinelApplication8401 {
    public static void main(String[] args) {
        SpringApplication.run(SentinelApplication8401.class,args);
    }
}
 
- 流控的兜底方法 【static】
 
package com.qiumin.myhandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.PathVariable;
public class MyBlockHandler {
    public static String handler1(@PathVariable("id") int id, BlockException exception){
        return "兜底方法=======1!!!";
    }
    public static String handler2(@PathVariable("id") int id,BlockException exception){
        return "兜底方法=======2!!!";
    }
}
 
- controller
 
package com.qiumin.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.qiumin.myhandler.MyBlockHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class SentinelTestController {
    @Value("${server.port}")
    private String port;
    @GetMapping("/testA/{id}")
    @SentinelResource(value = "testA",blockHandlerClass = MyBlockHandler.class,blockHandler = "handler2" ,fallback = "testA_deal")    //fallback管java异常,blockHandler管流控
    public String TestA(@PathVariable("id") int id){
        if(id>4){
            throw new IllegalArgumentException("非法参数异常!!!");
        }
        return port+"调用服务成功!!!"+id;
    }
    //因出现故障而导致服务降级时的兜底方法
    public String testA_deal(@PathVariable("id") int id,Throwable e){
        return e.getMessage()+"非法参数为: "+id;
    }
}
 
- 访问测试 
  
- 访问 http://localhost:8401/testA/2
 - fallback管java异常,blockHandler管流控。
 - 当出现流控异常时,程序没异常时会触发流控异常的兜底方法。
 - 当在流控范围内时,java程序有异常或超时时会触发 fallback 异常的兜底方法。
 - 注意:当两者都出现异常,即不符合流控规则同时又有java异常,这是触发的是流控的兜底方法。
 - @SentinelResource(value = “testA”,blockHandlerClass = MyBlockHandler.class,blockHandler = “handler2” ,fallback = “testA_deal”)
 - 当我们是以 @SentinelResource中的value的值添加流控时,不符合规则时是触发我们自定义的处理方法,而以url来添加流控规则时,不符合规则时触发的是sentinel默认的处理方法。
 
 
7.2 openfeign整合sentinel
- 参照cloudalibaba-sentinel8401创建cloudalibaba-sentinel8402,只是端口号不同,其他一模一样。【这里创建一模一样的主要演示的是负载均衡调用】
 

- 创建服务的消费者客户端
 

- pom
 
<?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>springcloud2022</artifactId>
        <groupId>com.qiu</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cloudalibaba-sentinel-openfeign-consumer8888</artifactId>
    <properties>
        <maven.compiler.source>15</maven.compiler.source>
        <maven.compiler.target>15</maven.compiler.target>
    </properties>
    <dependencies>
        <!--负载均衡-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--nacos服务发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
            <version>2.2.0.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--nacos配置中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-nacos-config</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>
        <!--sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--图形化处理-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <version>2.6.5</version>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version>2.6.5</version>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
 
- yaml
 
server:
  port: 8888
spring:
  application:
    name: cloudalibaba-sentinel-openfeign-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719
management:
  endpoints:
    web:
      exposure:
        include: '*'
feign:
  sentinel:
    enabled: true   #开启sentinel
 
- 主启动类
 
package com.qiumin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ConsumerSentinelApplication8888 {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerSentinelApplication8888.class,args);
    }
}
 
- client 【远程服务调用】
 
@Repository
@FeignClient(value = "cloudalibaba-sentinel-service",fallback = FallbeackService.class)
public interface ServiceClient {
    @GetMapping("/testA/{id}")
    String TestA(@PathVariable("id") int id);
}
 
- 客户端自己的服务降级方法
 
package com.qiumin.service;
import com.qiumin.client.ServiceClient;
import org.springframework.stereotype.Component;
/**
 * @Author: qiumin
 * @Description: love code
 * @Date: Created in 17:45 2022/4/12
 */
@Component
public class FallbeackService implements ServiceClient {
    @Override
    public String TestA(int id) {
        return "服务降级!!!";
    }
}
 
- controller
 
package com.qiumin.controller;
import com.qiumin.client.ServiceClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class ConsumerSentinelController {
    @Autowired
    private ServiceClient serviceClient;
    @GetMapping("/test/{id}")
    public String test(@PathVariable("id") int id){
        return serviceClient.TestA(id);
    }
}
 
- 通过客户端访问测试 
  
- 会有负载均衡效果
 - 会有客户端的服务降级效果 【关闭后台服务即可,两个都关,以为有集群效果】
 - 会有服务端的服务降级效果 【参数大于4时】
 - 添加流控规则时会有流控的处理方法的调用
 
 
8、sentinel持久化
- 解决方式:
 
将限流配置规则持久化进nacos保存,只要不将nacos中的配置删除,那么流控规则及其它的规则就不会随服务端重启而丢失
首先在nacos中添加流控配置:
流控规则JSON格式
[
    {
        "resource":"testAA",
        "limitApp":"default",
        "grade":1,
        "count":1,
        "stratrgy":0,
        "controlBehavior":0,
        "clusterMode":false
    }
]
 

- 
 
依赖:
<?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>springcloud2022</artifactId>
        <groupId>com.qiu</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cloudalibaba-sentinel-service8401</artifactId>
    <properties>
        <maven.compiler.source>15</maven.compiler.source>
        <maven.compiler.target>15</maven.compiler.target>
    </properties>
    <dependencies>
        <!--持久化-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <!--nacos服务发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>
        <!--nacos配置中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-nacos-config</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>
        <!--sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--图形化处理-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <version>2.6.5</version>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version>2.6.5</version>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
 
yaml:
server:
  port: 8401
spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719
      datasource:
        da1:   #持久化配置【流控规则】
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow
management:
  endpoints:
    web:
      exposure:
        include: '*'
 
controller:
package com.qiumin.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.qiumin.myhandler.MyBlockHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class SentinelTestController {
    @Value("${server.port}")
    private String port;
    @GetMapping("/testA/{id}")
    @SentinelResource(value = "testAA",blockHandlerClass = MyBlockHandler.class,blockHandler = "handler2"
            ,fallback = "testA_deal")
    public String TestA(@PathVariable("id") int id){
        if(id>4){
            throw new IllegalArgumentException("非法参数异常!!!");
        }
        return Thread.currentThread().getName()+"\t"+"测试流量控制Qps"+"成功!!!"+"端口号为: "+port+"------"+id;
    }
    public String testA_deal(@PathVariable("id") int id,Throwable e){
        return port+"====="+e.getMessage()+"非法参数为: "+id;
    }
}
 
MyHandler
package com.qiumin.myhandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.PathVariable;
public class MyBlockHandler {
    public static String handler1(@PathVariable("id") int id, BlockException exception){
        return "兜底方法=======1!!!";
    }
    public static String handler2(@PathVariable("id") int id,BlockException exception){
        return "兜底方法=======2!!!";
    }
}
 
- 启动服务测试: 
  
- 启动nacos
 - 启动sentinel
 - 启动该服务
 - 可以看到sentinel启动后就要流控规则,服务重启后还是会存在。即已经持久化。
 
 
qiumin










