熔断器Hystrix及服务监控Dashboard

服务雪崩效应

当一个请求依赖多个服务的时候:

正常情况下的访问 

但是,当请求的服务中出现无法访问、异常、超时等问题时(图中的I),那么用户的请求将会被阻塞。

如果多个用户的请求中,都存在无法访问的服务,那么他们都将陷入阻塞的状态中。

Hystrix的引入,可以通过服务熔断和服务降级来解决这个问题。

服务熔断服务降级

Hystrix断路器简介

hystrix对应的中文名字是“豪猪”,豪猪周身长满了刺,能保护自己不受天敌的伤害,代表了一种防御机制,

这与hystrix本身的功能不谋而合,因此Netflix团队将该框架命名为Hystrix,并使用了对应的卡通形象做作为logo。

 

在一个分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,

这个就是Hystrix需要做的事情。Hystrix提供了熔断、隔离、Fallback、cache、监控等功能,能够在一个、或多个依赖同时出现问题时保证系统依然可用。

Hystrix服务熔断服务降级@HystrixCommand fallbackMethod

熔断机制是应对雪崩效应的一种微服务链路保护机制。

当某个服务不可用或者响应时间超时,会进行服务降级,进而熔断该节点的服务调用,快速返回自定义的错误影响页面信息。

 

我们写个项目来测试下;

 

我们写一个新的带服务熔断的服务提供者项目 microservice-student-provider-hystrix-1004

配置和 代码 都复制一份到这个项目里;

 

然后修改;

1,pom.xml加下 hystrix支持

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 4     <modelVersion>4.0.0</modelVersion>
 5     <parent>
 6         <groupId>com.yuan</groupId>
 7         <artifactId>t226microservice</artifactId>
 8         <version>1.0-SNAPSHOT</version>
 9     </parent>
10     <artifactId>microservice-student-provider-hystrix-1004</artifactId>
11 
12     <properties>
13         <java.version>1.8</java.version>
14     </properties>
15     <dependencies>
16         <dependency>
17             <groupId>org.springframework.boot</groupId>
18             <artifactId>spring-boot-starter-web</artifactId>
19         </dependency>
20         <dependency>
21             <groupId>org.springframework.boot</groupId>
22             <artifactId>spring-boot-starter-test</artifactId>
23             <scope>test</scope>
24         </dependency>
25         <dependency>
26             <groupId>org.springframework.boot</groupId>
27             <artifactId>spring-boot-starter-data-jpa</artifactId>
28         </dependency>
29         <dependency>
30             <groupId>mysql</groupId>
31             <artifactId>mysql-connector-java</artifactId>
32         </dependency>
33         <dependency>
34             <groupId>org.springframework.boot</groupId>
35             <artifactId>spring-boot-starter-tomcat</artifactId>
36         </dependency>
37         <dependency>
38             <groupId>com.alibaba</groupId>
39             <artifactId>druid-spring-boot-starter</artifactId>
40         </dependency>
41         <!--  修改后立即生效,热部署  -->
42         <dependency>
43             <groupId>org.springframework</groupId>
44             <artifactId>springloaded</artifactId>
45         </dependency>
46         <dependency>
47             <groupId>org.springframework.boot</groupId>
48             <artifactId>spring-boot-devtools</artifactId>
49         </dependency>
50         <dependency>
51             <groupId>com.yuan</groupId>
52             <artifactId>microservice-common</artifactId>
53             <version>1.0-SNAPSHOT</version>
54             <scope>compile</scope>
55         </dependency>
56         <!--添加注册中心Eureka相关配置-->
57         <dependency>
58             <groupId>org.springframework.cloud</groupId>
59             <artifactId>spring-cloud-starter-eureka</artifactId>
60         </dependency>
61         <dependency>
62             <groupId>org.springframework.cloud</groupId>
63             <artifactId>spring-cloud-starter-config</artifactId>
64         </dependency>
65         <!-- actuator监控引入 -->
66         <dependency>
67             <groupId>org.springframework.boot</groupId>
68             <artifactId>spring-boot-starter-actuator</artifactId>
69         </dependency>
70         <dependency>
71             <groupId>com.yuan</groupId>
72             <artifactId>microservice-student-provider-1001</artifactId>
73             <version>1.0-SNAPSHOT</version>
74             <scope>compile</scope>
75         </dependency>
76         <!--Hystrix相关依赖-->
77         <dependency>
78             <groupId>org.springframework.cloud</groupId>
79             <artifactId>spring-cloud-starter-hystrix</artifactId>
80         </dependency>
81         <dependency>
82             <groupId>com.yuan</groupId>
83             <artifactId>microservice-student-provider</artifactId>
84             <version>1.0-SNAPSHOT</version>
85             <scope>compile</scope>
86         </dependency>
87 
88     </dependencies>
89     <build>
90         <plugins>
91             <plugin>
92                 <groupId>org.springframework.boot</groupId>
93                 <artifactId>spring-boot-maven-plugin</artifactId>
94             </plugin>
95         </plugins>
96     </build>
97 
98 </project>

application.yml修改下端口和实例名称

 1 server:
 2   port: 1004
 3   context-path: /
 4 spring:
 5   datasource:
 6     type: com.alibaba.druid.pool.DruidDataSource
 7     driver-class-name: com.mysql.jdbc.Driver
 8     url: jdbc:mysql://localhost:3306/j2ee?useUnicode=true&characterEncoding=utf8
 9     username: root
10     password: 12345
11   jpa:
12     hibernate:
13       ddl-auto: update
14     show-sql: true
15   application:
16     name: microservice-student
17   profiles: provider-hystrix-1004
18 
19 eureka:
20   instance:
21     hostname: localhost
22     appname: microservice-student
23     instance-id: microservice-student:1004
24     prefer-ip-address: true
25   client:
26     service-url:
27       defaultZone: http://eureka2001.yuan.com:2001/eureka/,http://eureka2002.yuan.com:2002/eureka/,http://eureka2003.yuan.com:2003/eureka/
28 
29 info:
30   groupId: com.yuan.testSpringcloud
31   artifactId: microservice-student-provider-hystrix-1004
32   version: 1.0-SNAPSHOT
33   userName: http://yuan.com
34   phone: 123456

启动类StudentProviderHystrixApplication_1004加下注解支持 @EnableCircuitBreaker

 1 package com.yuan.microservicestudentproviderhystrix1004;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 import org.springframework.boot.autoconfigure.domain.EntityScan;
 6 import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
 7 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
 8 
 9 @EnableCircuitBreaker
10 @EntityScan("com.yuan.*.*")
11 @EnableEurekaClient
12 @SpringBootApplication
13 public class MicroserviceStudentProviderHystrix1004Application {
14 
15     public static void main(String[] args) {
16         SpringApplication.run(MicroserviceStudentProviderHystrix1004Application.class, args);
17     }
18 
19 }

4,服务提供者1004中controller新增

 1 package com.yuan.microservicestudentproviderhystrix1004.controller;
 2 
 3 import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
 4 import com.yuan.microservicecommon.entity.Student;
 5 import com.yuan.microservicestudentproviderhystrix1004.service.StudentService;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.beans.factory.annotation.Value;
 8 import org.springframework.web.bind.annotation.*;
 9 
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.Map;
13 
14 @RestController
15 @RequestMapping("/student")
16 public class StudentProviderController {
17  
18     @Autowired
19     private StudentService studentService;
20 
21     @Value("${server.port}")
22     private String port;
23      
24     @PostMapping(value="/save")
25     public boolean save(Student student){
26         try{
27             studentService.save(student);  
28             return true;
29         }catch(Exception e){
30             return false;
31         }
32     }
33      
34     @GetMapping(value="/list")
35     public List<Student> list(){
36         return studentService.list();
37     }
38      
39     @GetMapping(value="/get/{id}")
40     public Student get(@PathVariable("id") Integer id){
41         return studentService.findById(id);
42     }
43      
44     @GetMapping(value="/delete/{id}")
45     public boolean delete(@PathVariable("id") Integer id){
46         try{
47             studentService.delete(id);
48             return true;
49         }catch(Exception e){
50             return false;
51         }
52     }
53 
54     @RequestMapping("/ribbon")
55     public String ribbon(){
56         return "工号【"+port+"】正在为您服务";
57     }
58 
59     /**
60      * 测试Hystrix服务降级
61      * @return
62      * @throws InterruptedException
63      */
64     @ResponseBody
65     @GetMapping(value="/hystrix")
66     @HystrixCommand(fallbackMethod="hystrixFallback")
67     public Map<String,Object> hystrix() throws InterruptedException{
68 //        Thread.sleep(2000);
69         Map<String,Object> map=new HashMap<String,Object>();
70         map.put("code", 200);
71         map.put("info","工号【"+port+"】正在为您服务");
72         return map;
73     }
74 
75     public Map<String,Object> hystrixFallback() throws InterruptedException{
76         Map<String,Object> map=new HashMap<String,Object>();
77         map.put("code", 500);
78         map.put("info", "系统【"+port+"】繁忙,稍后重试");
79         return map;
80     }
81 
82 }

这里正常访问 返回的是 200  业务数据xxxxx 

但是我们这里Thread.sleep(2000) 模拟超时;

这里的话 我们加上@HystrixCommand注解 以及 fallbackMethod

表明这个方法我们再 没有异常以及没有超时(hystrix默认1秒算超时)的情况,才返回正常的业务数据;

否则,进入我们fallback指定的本地方法,我们搞的是500  系统出错,稍后重试,有效的解决雪崩效应,以及返回给用户界面

很好的报错提示信息;

microservice-student-consumer-80项目也要对应的加个方法

 1 package com.yuan.microservicestudentconsumer80.controller;
 2 
 3 import com.yuan.microservicecommon.entity.Student;
 4 import org.springframework.beans.factory.annotation.Autowired;
 5 import org.springframework.web.bind.annotation.*;
 6 import org.springframework.web.client.RestTemplate;
 7 
 8 import java.util.List;
 9 import java.util.Map;
10 
11 @RestController
12 @RequestMapping("/student")
13 public class StudentConsumerController {
14 
15     private final static String SERVER_IP_PORT = "http://MICROSERVICE-STUDENT";
16  
17      @Autowired
18      private RestTemplate restTemplate;
19       
20      @PostMapping(value="/save")
21      private boolean save(Student student){
22          return restTemplate.postForObject(SERVER_IP_PORT+"/student/save", student, Boolean.class);
23      }
24       
25     @GetMapping(value="/list")
26     public List<Student> list(){
27         return restTemplate.getForObject(SERVER_IP_PORT+"/student/list", List.class);
28     }
29      
30     @GetMapping(value="/get/{id}")
31     public Student get(@PathVariable("id") Integer id){
32         return restTemplate.getForObject(SERVER_IP_PORT+"/student/get/"+id, Student.class);
33     }
34      
35     @GetMapping(value="/delete/{id}")
36     public boolean delete(@PathVariable("id") Integer id){
37         try{
38             restTemplate.getForObject(SERVER_IP_PORT+"/student/delete/"+id, Boolean.class);
39             return true;
40         }catch(Exception e){
41             return false;
42         }
43     }
44     @RequestMapping("/ribbon")
45     public String ribbon(){
46         return restTemplate.getForObject(SERVER_IP_PORT + "/student/ribbon", String.class);
47     }
48 
49     /**
50      * 测试Hystrix服务降级
51      * @return
52      */
53     @GetMapping(value="/hystrix")
54     @ResponseBody
55     public Map<String,Object> hystrix(){
56         return restTemplate.getForObject(SERVER_IP_PORT+"/student/hystrix/", Map.class);
57     }
58 
59 }

然后我们来测试下

先启动三个eureka,再启动带hystrix的provider,最后启动普通的consumer;

 

浏览器:http://localhost/student/hystrix

返回:

因为 Hystrix默认1算超时,所有 sleep了2秒 所以进入自定义fallback方法,防止服务雪崩;

 

我们这里改sleep修改成100毫秒;

Hystrix默认超时时间设置

Hystrix默认超时时间是1秒,我们可以通过hystrix源码看到,

找到 hystrix-core.jar com.netflix.hystrix包下的HystrixCommandProperties类

default_executionTimeoutInMilliseconds属性局势默认的超时时间

默认1000毫秒 1秒

 

我们系统里假如要自定义设置hystrix的默认时间的话;

application.yml配置文件加上

1 hystrix:
2   command:
3     default:
4       execution:
5         isolation:
6           thread:
7             timeoutInMilliseconds: 3000

改成3秒  然后 我们代码里sleep修改成2秒测试;

测试OK

 

sleep修改成4秒;

Hystrix服务监控Dashboard

Hystrix服务监控Dashboard仪表盘

 

Hystrix提供了 准实时的服务调用监控项目Dashboard,能够实时记录通过Hystrix发起的请求执行情况,

可以通过图表的形式展现给用户看。

 

我们新建项目:microservice-student-consumer-hystrix-dashboard-90

加依赖:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 4     <modelVersion>4.0.0</modelVersion>
 5     <parent>
 6         <groupId>com.yuan</groupId>
 7         <artifactId>t226microservice</artifactId>
 8         <version>1.0-SNAPSHOT</version>
 9     </parent>
11     <artifactId>microservice-student-consumer-hystrix-dashboard-90</artifactId>
12 
13     <properties>
14         <java.version>1.8</java.version>
15     </properties>
16 
17     <dependencies>
18         <dependency>
19             <groupId>org.springframework.boot</groupId>
20             <artifactId>spring-boot-starter</artifactId>
21         </dependency>
22 
23         <dependency>
24             <groupId>org.springframework.boot</groupId>
25             <artifactId>spring-boot-starter-test</artifactId>
26             <scope>test</scope>
27             <exclusions>
28                 <exclusion>
29                     <groupId>org.junit.vintage</groupId>
30                     <artifactId>junit-vintage-engine</artifactId>
31                 </exclusion>
32             </exclusions>
33         </dependency>
34         <!--Hystrix服务监控Dashboard依赖-->
35         <dependency>
36             <groupId>org.springframework.cloud</groupId>
37             <artifactId>spring-cloud-starter-hystrix</artifactId>
38         </dependency>
39         <dependency>
40             <groupId>org.springframework.cloud</groupId>
41             <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
42         </dependency>
43         <dependency>
44             <groupId>org.springframework.boot</groupId>
45             <artifactId>spring-boot-starter-actuator</artifactId>
46         </dependency>
47 
48     </dependencies>
49 
50     <build>
51         <plugins>
52             <plugin>
53                 <groupId>org.springframework.boot</groupId>
54                 <artifactId>spring-boot-maven-plugin</artifactId>
55             </plugin>
56         </plugins>
57     </build>
58 
59 </project>

application.yml配置

1 server:
2   port: 90
3   servlet:
4     context-path: /

新建启动类:StudentConsumerDashBoardApplication_90

加注解:@EnableHystrixDashboard

 1 package com.yuan.microservicestudentconsumerhystrixdashboard90;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 6 import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
 7 import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
 8 
 9 @SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
10 @EnableHystrixDashboard
11 public class MicroserviceStudentConsumerHystrixDashboard90Application {
12 
13     public static void main(String[] args) {
14         SpringApplication.run(MicroserviceStudentConsumerHystrixDashboard90Application.class, args);
15     }
16 
17 }

这样就完事了。

 

我们启动这个项目;

然后浏览器输入:http://localhost:90/hystrix

出现这个 就说明OK;

然后我们来测试下;

我们启动三个eureka,然后再启动microservice-student-provider-hystrix-1004

我们直接请求http://localhost:1004/student/hystrix

返回正常业务

指标含义:

各种情况:

谢谢观看!!!

原文地址:https://www.cnblogs.com/ly-0919/p/12007991.html