【SpringCloud】Spring Cloud Alibaba 之 Sentinel @SentinelResource使用(三十三)

项目准备

项目架构如下:

  

项目搭建

  参考:【SpringCloud】Spring Cloud Alibaba 之 Sentinel哨兵介绍入门(二十九) 

1、搭建一个Nacos服务

  参考项目搭建,用于做项目的注册中心及配置中心,并启动

2、搭建一个Sentinel控制台

  参考项目搭建,并启动

3、搭建2个nacos-payment-provider服务

  参考项目搭建,springcloud-provider-sentinel-payment9003 和 springcloud-provider-sentinel-payment9004 项目

  

  项目中PaymentController,如下:

 1 @RestController
 2 public class PaymentController {
 3     @Value("${server.port}")
 4     private String serverPort;
 5 
 6     public static HashMap<Long, Payment> hashMap = new HashMap<Long, Payment>();
 7 
 8     static {
 9         hashMap.put(1L, new Payment(1L, "aaaaaa"));
10         hashMap.put(2L, new Payment(2L, "bbbbbb"));
11         hashMap.put(3L, new Payment(3L, "cccccc"));
12     }
13 
14     @GetMapping(value = "/paymentSQL/{id}")
15     public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id) {
16         Payment payment = hashMap.get(id);
17         CommonResult<Payment> result = new CommonResult<Payment>(200, "from server port : " + serverPort, payment);
18         return result;
19     }
20 }

  项目中有2个实体类,CommonResult实体类如下:

 1 @Data
 2 @AllArgsConstructor
 3 @NoArgsConstructor
 4 public class CommonResult<T> {
 5 
 6     private int code;
 7     private String msg;
 8     private T data;
 9 
10     public CommonResult(int code, String msg) {
11         this.code = code;
12         this.msg = msg;
13     }
14 }

  Payment实体类

1 @Data
2 @AllArgsConstructor
3 @NoArgsConstructor
4 public class Payment {
5     private Long id;
6     private String serial;
7 }

  然后分别启动2个服务

3、搭建1个springcloud-consumer-sentinel-order7994服务(调用者)

  

  a、pom文件如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <parent>
 6         <artifactId>test-springcloud</artifactId>
 7         <groupId>com.test</groupId>
 8         <version>1.0-SNAPSHOT</version>
 9     </parent>
10     <modelVersion>4.0.0</modelVersion>
11 
12     <artifactId>springcloud-consumer-sentinel-order7994</artifactId>
13 
14     <dependencies>
15 
16         <!-- alibaba nacos sentinel -->
17         <dependency>
18             <groupId>com.alibaba.cloud</groupId>
19             <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
20             <version>2.2.1.RELEASE</version>
21             <exclusions>
22                 <exclusion>
23                     <groupId>com.fasterxml.jackson.dataformat</groupId>
24                     <artifactId>jackson-dataformat-xml</artifactId>
25                 </exclusion>
26             </exclusions>
27         </dependency>
28 
29         <!-- alibaba nacos -->
30         <dependency>
31             <groupId>com.alibaba.cloud</groupId>
32             <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
33         </dependency>
34 
35         <!-- openfeign -->
36         <dependency>
37             <groupId>org.springframework.cloud</groupId>
38             <artifactId>spring-cloud-starter-openfeign</artifactId>
39         </dependency>
40 
41         <!-- spring boot -->
42         <dependency>
43             <groupId>org.springframework.boot</groupId>
44             <artifactId>spring-boot-starter-web</artifactId>
45         </dependency>
46         <dependency>
47             <groupId>org.springframework.boot</groupId>
48             <artifactId>spring-boot-starter-actuator</artifactId>
49         </dependency>
50         <dependency>
51             <groupId>org.springframework.boot</groupId>
52             <artifactId>spring-boot-devtools</artifactId>
53             <scope>runtime</scope>
54             <optional>true</optional>
55         </dependency>
56         <dependency>
57             <groupId>org.projectlombok</groupId>
58             <artifactId>lombok</artifactId>
59             <optional>true</optional>
60         </dependency>
61         <dependency>
62             <groupId>org.springframework.boot</groupId>
63             <artifactId>spring-boot-starter-test</artifactId>
64             <scope>test</scope>
65         </dependency>
66 
67     </dependencies>
68 </project>
View Code

  b、application配置文件如下:

 1 # 端口
 2 server:
 3   port: 7994
 4 
 5 spring:
 6   application:
 7     name: nacos-order-consumer
 8   cloud:
 9     nacos:
10       discovery:
11         server-addr: localhost:8848
12     sentinel:
13       transport:
14         # 配置Sentinel DashBoard地址
15         dashboard: localhost:8080
16         # 应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer
17         # 默认8719端口,假如端口被占用,依次+1,直到找到未被占用端口
18         port: 8719
19 
20 
21 management:
22   endpoints:
23     web:
24       exposure:
25         include: '*'
View Code

  c、主启动类OrderMain7994

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 }

  d、配置类AppConfig,整合Ribbon服务调用

1 @Configuration
2 public class AppConfig {
3     @Bean
4     @LoadBalanced
5     public RestTemplate restTemplate() {
6         return new RestTemplate();
7     }
8 }

  e、controller内容如下:

 1 @RestController
 2 @Slf4j
 3 public class CircleBreakerController {
 4     public static final String SERVICE_URL = "http://nacos-payment-provider";
 5 
 6     @Autowired
 7     private RestTemplate restTemplate;
 8 
 9     @RequestMapping("/consumer/fallback/{id}")
10     public CommonResult<Payment> fallback(@PathVariable("id") Long id) {
11         CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class);
12         if (id == 4) {
13             throw new IllegalArgumentException("IllegalArgumentException, 非法参数");
14         } else if (result.getData() == null) {
15             throw new NullPointerException("NullPointerException,该ID没有对应的记录,空指针异常");
16         }
17 
18         return result;
19     }
20 
21 }

4、测试验证项目

  1)访问地址:http://localhost:7994/consumer/fallback/3,正常获取到provider服务提供者的内容

  

  2)访问地址:http://localhost:7994/consumer/fallback/4,抛异常,非法参数

  

  3)访问地址:http://localhost:7994/consumer/fallback/5,抛异常,空指针异常

  

@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指定的方法不处理异常

    

猜你喜欢

转载自www.cnblogs.com/h--d/p/12970060.html