@SentinelResource使用

1、@SentinelResource定义资源名

  1.1、修改CircleBreakerController中fallback方法,如下:

1 @RequestMapping("/consumer/fallback/{id}")
2 @SentinelResource(value = "fallback") // 没有配置
3 public CommonResult<Payment> fallback(@PathVariable("id") Long id) {
4     ...
5 }

  1.2、重新启动项目

  1.3、访问地址http://localhost:7994/consumer/fallback/3,并在sentinel控制台设置限流规则

    注意这里设置规则的时候,可以直接使用@SentinelResource的value作为资源名

    

  1.4、快速访问地址http://localhost:7994/consumer/fallback/3,限流成功

    

2、@SentinelResource 中的fallback

  fallback负责业务异常和限流时处理

  2.1、修改CircleBreakerController中fallback方法,如下:

复制代码
 1 @RequestMapping("/consumer/fallback/{id}")
 2 @SentinelResource(value = "fallback", fallback = "handlerFallback") // fallback负责业务异常和限流返回
 3 public CommonResult<Payment> fallback(@PathVariable("id") Long id) {
 4     ...
 5 }
 6 
 7 public CommonResult<Payment> handlerFallback(Long id, Throwable e) {
 8     Payment payment = new Payment(id, "null");
 9     return new CommonResult(500, "兜底异常处理handlerFallback,Exception内容:" + e.getMessage(), payment);
10 }  
复制代码

  2.2、重新启动项目

  2.3、访问地址http://localhost:7994/consumer/fallback/4,出现异常由fallback指定的方法处理

    

  2.4、在sentinel控制台设置限流规则,设置QPS为阀值为1

  2.5、快速访问地址http://localhost:7994/consumer/fallback/3,限流成功,限流返回内容为fallback指定的方法

    

3、@SentinelResource 中的blockHandler

  blockHandler只负责sentinel控制台配置违规

  3.1、修改CircleBreakerController中fallback方法,如下: 

复制代码
 1 @RequestMapping("/consumer/fallback/{id}")
 2 @SentinelResource(value = "fallback", blockHandler = "blockHandler") // blockHander只负责sentinel控制台配置违规
 3 public CommonResult<Payment> fallback(@PathVariable("id") Long id) {
 4     ...
 5 }
 6 
 7 public CommonResult<Payment> handlerFallback(Long id, Throwable e) {
 8     Payment payment = new Payment(id, "null");
 9     return new CommonResult(500, "兜底异常处理handlerFallback,Exception内容:" + e.getMessage(), payment);
10 }
11 
12 public CommonResult<Payment> blockHandler(Long id, BlockException blockException) {
13     Payment payment = new Payment(id, "null");
14     return new CommonResult(500, "blockHandler-Sentinel限流,Exception内容:" + blockException.getMessage(), payment);
15 } 
复制代码

  3.2、重新启动项目

  3.3、访问地址http://localhost:7994/consumer/fallback/4,返回参数非法异常

  3.4、在sentinel控制台设置限流规则,设置QPS为阀值为1

  3.4、快速访问地址http://localhost:7994/consumer/fallback/3,限流成功,限流返回内容为blockHandler指定的方法

    

4、@SentinelResource 中的fallback和blockHandler同时存在

  fallback负责处理异常,blockHandler负责sentinel控制台配置违规

  4.1、修改CircleBreakerController中fallback方法,如下:

1 @RequestMapping("/consumer/fallback/{id}")
2 @SentinelResource(value = "fallback", blockHandler = "blockHandler", fallback = "handlerFallback")
3 public CommonResult<Payment> fallback(@PathVariable("id") Long id) {
4     ...
5 }  

  4.2、重新启动项目

  4.3、访问地址http://localhost:7994/consumer/fallback/4,出现异常由fallback指定的方法处理

    

  4.4、在sentinel控制台设置限流规则,设置QPS为阀值为1

  4.4、快速访问地址http://localhost:7994/consumer/fallback/3,限流成功,限流返回内容为blockHandler指定的方法

    

5、@SentinelResource 中的exceptionsToIgnore

  排除fallback指定的方法不处理的异常

  5.1、修改CircleBreakerController中fallback方法,如下:

1 @RequestMapping("/consumer/fallback/{id}")
2 @SentinelResource(value = "fallback", blockHandler = "blockHandler", fallback = "handlerFallback",
3         exceptionsToIgnore = {IllegalArgumentException.class})
4 public CommonResult<Payment> fallback(@PathVariable("id") Long id) {
5     ...
6 }

  5.2、重新启动项目

  5.3、访问地址http://localhost:7994/consumer/fallback/4,出现参数异常直接显示,fallback指定的方法不处理异常

    

本章介绍Sentinel 与OpenFeign整合使用,

项目框架

  

feign整合

  2、主要是修改项目:springcloud-consumer-sentinel-order7994服务(调用者),引入openfeign依赖

1 <!-- openfeign -->
2 <dependency>
3     <groupId>org.springframework.cloud</groupId>
4     <artifactId>spring-cloud-starter-openfeign</artifactId>
5 </dependency>

    

    注意版本问题,本例使用版本

1 <spring-boot.version>2.2.5.RELEASE</spring-boot.version>
2 <spring-cloud.version>Hoxton.SR3</spring-cloud.version>
3 <spring-cloud-alibaba.version>2.1.0.RELEASE</spring-cloud-alibaba.version>

    Hoxton.SR1 中,fegin.context接口方法的定义为parseAndValidatateMetadata
    Hoxton.SR3 中,fegin.context接口方法的定义为parseAndValidateMetadata

    由于com.alibaba.cloud.sentinel.feign.SentinelContractHolder类中使用了fegin.context接口方法,导致可能出现版本冲突,可能报错:

    AbstractMethodError: com.alibaba.cloud.sentinel.feign.SentinelContractHolder.parseAndValidateMetadata

    所以在项目用需要引入2.2.1.RELEASE版的spring-cloud-starter-alibaba-sentinel,并排除com.fasterxml.jackson.dataformat依赖(避免返回xml内容)

复制代码
 1 <!-- alibaba nacos sentinel -->
 2 <dependency>
 3     <groupId>com.alibaba.cloud</groupId>
 4     <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
 5     <version>2.2.1.RELEASE</version>
 6     <exclusions>
 7         <exclusion>
 8             <groupId>com.fasterxml.jackson.dataformat</groupId>
 9             <artifactId>jackson-dataformat-xml</artifactId>
10         </exclusion>
11     </exclusions>
12 </dependency>
复制代码

  3、application.yml文件如下,激活Sentinel对Feign的支持:

# 端口
server:
  port: 7001
spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.186.128:8848
    sentinel:
      transport:
        # 配置dashboard地址
        dashboard: 192.168.186.128:8998
        # 应用与控制台交互的端口 默认8719
        port: 8719
# 激活feign对sentinel的支持
feign:
  sentinel:
    enabled: true
management:
  endpoints:
    web:
      exposure:
        include: '*'

 

  4、主启动,启用OpenFeign

复制代码
1 @SpringBootApplication
2 @EnableDiscoveryClient
3 @EnableFeignClients
4 public class OrderMain7994 {
5     public static void main(String[] args) {
6         SpringApplication.run(OrderMain7994.class, args);
7     }
8 }
复制代码

  5、定义Feign接口,如下:

1 @FeignClient(value = "nacos-payment-provider", fallback = PaymentFallbackService.class)
2 public interface PaymentService {
3 
4     @GetMapping(value = "/paymentSQL/{id}")
5     public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
6 }

  6、定义Feign接口实现类,用于服务降级

复制代码
1 @Component
2 public class PaymentFallbackService implements PaymentService{
3 
4     public CommonResult<Payment> paymentSQL(Long id) {
5         return new CommonResult<Payment>(500, "服务降级返回,----PaymentFallbackService-paymentSQL");
6     }
7 }
复制代码

  7、编写Controller,增加如下内容:

复制代码
1     // =======OpenFeign
2     @Autowired
3     private PaymentService paymentService;
4 
5     @GetMapping(value = "/consumer/paymentSQL/{id}")
6     public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id){
7         return  paymentService.paymentSQL(id);
8     }
复制代码

  8、测试

    1)启动项目

    2)使用地址:http://localhost:7994/consumer/paymentSQL/3,正常获取内容

      

    3)关闭服务提供者

    4)使用地址:http://localhost:7994/consumer/paymentSQL/3,服务降级

      

在使用Sentinel我们发现,只要重新启动Sentinel的Java 客户端服务,Sentinel控制台配置的限流规则,就清空不存在了,下面介绍怎么持久化Sentinel规则

Sentinel 持久化规则

  本例介绍Sentinel从Nacos配置中心读取应用的限流降级配置规则

  1、打开cloud-sentinel-service8401项目

  2、修改POM文件,增加依赖sentinel数据nacos,如下:

    <dependencies>

        <!--datasource-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <!--sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

    </dependencies>

 

  3、修改application.yml文件,如下:

# 端口
server:
  port: 8401
spring:
  application:
    name: alibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.186.128:8848
    sentinel:
      transport:
        # 配置Sentinel DashBoard地址
        dashboard: 192.168.186.128:8998
        # 应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer
        # 默认8719端口,假如端口被占用,依次+1,直到找到未被占用端口
        port: 8719
      datasource:
        ds1:
          nacos:
            server-addr: 192.168.186.128:8848
            dataId: alibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow
management:
  endpoints:
    web:
      exposure:
        include: '*'

 

  4、在Nacos配置中心,增加配置

    

    配置说明:

      1)resource:资源名称;

      2)limitApp:来源应用;

      3)grade:阀值类型,0表示线程数,1表示QPS

      4)count:单机阀值;

      5)strategy:流控模式,0表示直接,1表示关联,2表示链路;

      6)controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示排队等待;

      7)clusterMode:是否集群

  5、启动项目测试

    1)启动项目

    2)快速访问地址:http://localhost:8401/testB,服务被限流,Sentinel持久化规则已生效