Spring cloud alibaba——sentinel(三)——@SentinelResource

Sentinel服务熔断环境搭建

为了测试熔断保护机制,首先搭建一个服务环境,服务环境如下:
springcloud的依赖版本记得选2.2.X
在这里插入图片描述
搭建方式跟之前差不多

一、共用类commons

服务cloudalibaba-commons,后面9003和9004会引用这个类

package com.cloud.cloudalibabacommons.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 响应类
 * @param <T>
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class JsonResult<T> {
    
    

    /**
     * 响应码
     */
    private Integer code;

    /**
     * 响应数据
     */
    private T data;

}

二、服务提供者9003,90004搭建

9003和9004项目结构、代码相同,只是端口号不一样
pom依赖:

<!--   nacos依赖     -->
   <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

    <!--   commons依赖     -->
    <dependency>
        <groupId>com.cloud</groupId>
        <artifactId>cloudalibaba-commons</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

application.yml

server:
  port: 9003


spring:
  application:
    name: nacos-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

management:
  endpoints:
    web:
      exposure:
        include: '*'

启动类记得添加@EnableDiscoveryClient注解

控制器类:

package com.cloud.cloudalibabaprovider9004.controller;

import com.cloud.cloudalibabacommons.entity.JsonResult;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;


@RestController
@RequestMapping("data")
public class DataController {
    
    

    @Value("${server.port}")
    private String serverPort;

    public static HashMap<Long,String> dataMap = new HashMap<>();
    //模仿数据库存储数据
    static{
    
    
        dataMap.put(1L,"鼠标");
        dataMap.put(2L,"键盘");
        dataMap.put(3L,"耳机");
    }

    @GetMapping("info/{id}")
    public JsonResult<String> info(@PathVariable("id") Long id){
    
    
        return new JsonResult<String>(200,serverPort+":  "+dataMap.get(id));
    }
}

二、服务消费者8084模块搭建

pom依赖

  <!--   nacos依赖     -->
     <dependency>
         <groupId>com.alibaba.cloud</groupId>
         <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
     </dependency>

     <!--   sentinel依赖     -->
     <dependency>
         <groupId>com.alibaba.cloud</groupId>
         <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
     </dependency>
	 <dependency>
        <groupId>com.cloud</groupId>
        <artifactId>cloudalibaba-commons</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

配置文件application.yml

server:
  port: 8084

spring:
  application:
    name: naocs-customer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        #默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
        port: 8719
        #配置Sentinel dashboard地址
        dashboard: 8080

# 消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
  nacos-user-service: http://nacos-provider

启动类

@SpringBootApplication
@EnableDiscoveryClient
public class CloudalibabaCustomer8084Application {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(CloudalibabaCustomer8084Application.class, args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
    
    
        return new RestTemplate();
    }
}

Controller类

@RestController
@RequestMapping("demo")
public class DemoController {
    
    

    @Autowired
    private RestTemplate restTemplate;

    @Value("${service-url.nacos-user-service}")
    private String SERVICE_URL;

    @GetMapping("info/{id}")
    public JsonResult<String> fallbackInfo(@PathVariable("id") Long id){
    
    
        JsonResult<String> jsonResult = restTemplate.getForObject(SERVICE_URL+"/data/info/"+id,JsonResult.class);
        return jsonResult;
    }
}

@SentinelResource注解

属性

@SentinelResource官方文档说明

  • value 资源名称,必需项(不能为空)
  • blockHandler / blockHandlerClass: blockHandler 对应处理 BlockException 的函数名称,可选项。之前有提到过blockHandler和blockHanlderClass用法
  • fallback:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常。
  • exceptionsToIgnore:用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。

fallback用法

@RestController
@RequestMapping("demo")
public class DemoController {
    
    

    @Autowired
    private RestTemplate restTemplate;

    @Value("${service-url.nacos-user-service}")
    private String SERVICE_URL;

    @GetMapping("info/{id}")
    @SentinelResource(value = "info", fallback = "fallBackHandler", exceptionsToIgnore = {
    
    NullPointerException.class})
    /**
     * 1.fallback属性定义本方法中一旦捕获到异常,由什么方法处理
     * 2.exceptionsToIgnore定义不处理的异常,
     *
     */
    public JsonResult<String> fallbackInfo(@PathVariable("id") Long id){
    
    
        if(id<3){
    
    
            JsonResult<String> jsonResult = restTemplate.getForObject(SERVICE_URL+"/data/info/"+id,JsonResult.class);
            return jsonResult;
        }else if(id>10){
    
    
            throw new RuntimeException("----------RuntimeException----------");
        }
        throw new NullPointerException("没有查询到该数据");
    }

    /**
     * 1.方法名对应fallBack定义的名称
     * 2.方法修饰符必须为public
     * 3.方法参数必须和@SentinelResource修饰的方法相同
     * 4.参数需要多添加一个Throwable参数
     * @param id
     * @param e
     * @return
     */
    public JsonResult<String> fallBackHandler(Long id,Throwable e){
    
    
        return new JsonResult<String>(441,"NullPointerException");
    }
}

为了提高服用性,避免多个@SentinelResource指定方法带来重复,也可以使用fallbackClass指定一个固定的类来处理

    @GetMapping("info/{id}")
    /**
     * 1.fallback属性定义本方法中一旦捕获到异常,由什么方法处理
     * 2.fallBackClass和fallback共同出现时,由统一的类中的方法处理异常
     */
    @SentinelResource(value = "info",
            fallback = "exceptionHandler",
            fallbackClass = {
    
    FallbackHandler.class})
    public JsonResult<String> fallbackInfo(@PathVariable("id") Long id){
    
    
        if(id<3){
    
    
            JsonResult<String> jsonResult = restTemplate.getForObject(SERVICE_URL+"/data/info/"+id,JsonResult.class);
            return jsonResult;
        }
        throw new NullPointerException("没有查询到该数据");
    }

处理异常的类

package com.cloud.cloudalibabacustomer8084.hanlder;


import com.cloud.cloudalibabacommons.entity.JsonResult;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class FallbackHandler {
    
    

    /**
     * 注意对应的函数必需为 static 函数,否则无法解析。
     * 参数必须和@Sentinel注解的参数相同,并且需要多一个Throwable
     * @param e
     * @return
     */
    public static JsonResult<String> exceptionHandler(Long id,Throwable e){
    
    
        log.info("fffffff");
        return new JsonResult<String>(446,"访问异常");
    }
}


blockHolder和fallbackHolder的区别

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44712778/article/details/125682854