熔断器Hystrix及服务监控Dashboard 服务雪崩效应

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

正常情况下的访问 

熔断器Hystrix及服务监控Dashboard
服务雪崩效应

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

熔断器Hystrix及服务监控Dashboard
服务雪崩效应

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

熔断器Hystrix及服务监控Dashboard
服务雪崩效应

Hystrix的引入,可以

服务熔断服务降级

Hystrix断路器简介

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

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

通过服务熔断和服务降级来解决这个问题。

 熔断器Hystrix及服务监控Dashboard
服务雪崩效应

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

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

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

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

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

 新j建的带服务熔断的服务提供者项目 

microservice-student-provider-hystrix-1004

配置pom.xml

  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.javaqi</groupId>
  7         <artifactId>qimicroservice</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 
 16     <dependencies>
 17         <dependency>
 18             <groupId>com.javaqi</groupId>
 19             <artifactId>microservice-common</artifactId>
 20         </dependency>
 21         <dependency>
 22             <groupId>org.springframework.boot</groupId>
 23             <artifactId>spring-boot-starter-web</artifactId>
 24         </dependency>
 25         <dependency>
 26             <groupId>org.springframework.boot</groupId>
 27             <artifactId>spring-boot-starter-test</artifactId>
 28             <scope>test</scope>
 29         </dependency>
 30         <dependency>
 31             <groupId>org.springframework.boot</groupId>
 32             <artifactId>spring-boot-starter-data-jpa</artifactId>
 33         </dependency>
 34         <dependency>
 35             <groupId>mysql</groupId>
 36             <artifactId>mysql-connector-java</artifactId>
 37         </dependency>
 38         <dependency>
 39             <groupId>org.springframework.boot</groupId>
 40             <artifactId>spring-boot-starter-tomcat</artifactId>
 41         </dependency>
 42         <dependency>
 43             <groupId>com.alibaba</groupId>
 44             <artifactId>druid-spring-boot-starter</artifactId>
 45         </dependency>
 46         <!--  修改后立即生效,热部署  -->
 47         <dependency>
 48             <groupId>org.springframework</groupId>
 49             <artifactId>springloaded</artifactId>
 50         </dependency>
 51         <dependency>
 52             <groupId>org.springframework.boot</groupId>
 53             <artifactId>spring-boot-devtools</artifactId>
 54         </dependency>
 55 
 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         <dependency>
 66             <groupId>com.javaqi</groupId>
 67             <artifactId>microservice-common</artifactId>
 68             <version>1.0-SNAPSHOT</version>
 69             <scope>compile</scope>
 70         </dependency>
 71 
 72         <!-- actuator监控引入 -->
 73         <dependency>
 74             <groupId>org.springframework.boot</groupId>
 75             <artifactId>spring-boot-starter-actuator</artifactId>
 76         </dependency>
 77 
 78         <!--Hystrix相关依赖-->
 79         <dependency>
 80             <groupId>org.springframework.cloud</groupId>
 81             <artifactId>spring-cloud-starter-hystrix</artifactId>
 82         </dependency>
 83         <dependency>
 84             <groupId>com.javaqi</groupId>
 85             <artifactId>microservice-student-provider</artifactId>
 86             <version>1.0-SNAPSHOT</version>
 87             <scope>compile</scope>
 88         </dependency>
 89 
 90     </dependencies>
 91 
 92     <build>
 93         <plugins>
 94             <plugin>
 95                 <groupId>org.springframework.boot</groupId>
 96                 <artifactId>spring-boot-maven-plugin</artifactId>
 97             </plugin>
 98         </plugins>
 99     </build>
100 
101 </project>

l修改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/xufanqi?useUnicode=true&characterEncoding=utf8
 9     username: root
10     password: 123
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.javaqi.com:2001/eureka/,http://eureka2002.javaqi.com:2002/eureka/,http://eureka2003.javaqi.com:2003/eureka/
28 
29 hystrix:
30   command:
31     default:
32       execution:
33         isolation:
34           thread:
35             timeoutInMilliseconds: 3000
36 info:
37   groupId: com.javaxl.testSpringcloud
38   artifactId: microservice-student-provider-hystrix-1004
39   version: 1.0-SNAPSHOT
40   userName: http://javaqi.com
41   phone: 123456

StudentProviderHystrixApplication_1004加下注解支持

@EnableCircuitBreaker    

 1 package com.javaqi.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.javaqi.*.*")
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 }

controller

服务提供者1004中新增

StudentProviderController 
 1 package com.javaqi.microservicestudentproviderhystrix1004.controller;
 2 
 3 import com.javaqi.microservicecommon.entity.Student;
 4 import com.javaqi.microservicestudentproviderhystrix1004.service.StudentService;
 5 import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
 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 
61     /**
62      * 测试Hystrix服务降级
63      * @return
64      * @throws InterruptedException
65      */
66     @ResponseBody
67     @GetMapping(value="/hystrix")
68     @HystrixCommand(fallbackMethod="hystrixFallback")
69     public Map<String,Object> hystrix() throws InterruptedException{
70        Thread.sleep(4000);
71         Map<String,Object> map=new HashMap<String,Object>();
72         map.put("code", 200);
73         map.put("info","工号【"+port+"】正在为您服务");
74         return map;
75     }
76 
77     public Map<String,Object> hystrixFallback() throws InterruptedException{
78         Map<String,Object> map=new HashMap<String,Object>();
79         map.put("code", 500);
80         map.put("info", "系统【"+port+"】繁忙,稍后重试");
81         return map;
82     }
83 }

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

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

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

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

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

很好的报错提示信息;

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

 1 package com.javaqi.microservicestudentconsumerfeign80.controller;
 2 
 3 import com.javaqi.microservicecommon.entity.Student;
 4 import com.javaqi.microservicecommon.service.StudentClientService;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.web.bind.annotation.*;
 7 import org.springframework.web.client.RestTemplate;
 8 
 9 import java.util.List;
10 
11 @RestController
12 @RequestMapping("/student")
13 public class StudentConsumerController {
14 
15     @Autowired
16     private StudentClientService studentClientService;
17 
18     @Autowired
19     private RestTemplate restTemplate;
20 
21     @PostMapping(value = "/save")
22     private boolean save(Student student) {
23         return studentClientService.save(student);
24     }
25 
26     @GetMapping(value = "/list")
27     public List<Student> list() {
28         return studentClientService.list();
29     }
30 
31     @GetMapping(value = "/get/{id}")
32     public Student get(@PathVariable("id") Integer id) {
33         return studentClientService.get(id);
34     }
35 
36     @GetMapping(value = "/delete/{id}")
37     public boolean delete(@PathVariable("id") Integer id) {
38         try {
39             studentClientService.delete(id);
40             return true;
41         } catch (Exception e) {
42             return false;
43         }
44     }
45 
46     @RequestMapping("/ribbon")
47     public String ribbon(){
48         return studentClientService.ribbon();
49     }
50 }

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

 熔断器Hystrix及服务监控Dashboard
服务雪崩效应

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

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

熔断器Hystrix及服务监控Dashboard
服务雪崩效应

Hystrix默认超时时间设置

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

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

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

熔断器Hystrix及服务监控Dashboard
服务雪崩效应

默认1000毫秒 1秒

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

application.yml配置文件加上

熔断器Hystrix及服务监控Dashboard
服务雪崩效应

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

熔断器Hystrix及服务监控Dashboard
服务雪崩效应

 sleep修改成4秒;

熔断器Hystrix及服务监控Dashboard
服务雪崩效应

Hystrix服务监控Dashboard

Hystrix服务监控Dashboard仪表盘

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

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

我们新建项目:

microservice-student-consumer-hystrix-dashboard-90

pom

 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.javaqi</groupId>
 7         <artifactId>qimicroservice</artifactId>
 8         <version>1.0-SNAPSHOT</version>
 9     </parent>
10     <artifactId>microservice-student-consumer-hystrix-dashboard-90</artifactId>
11 
12     <properties>
13         <java.version>1.8</java.version>
14     </properties>
15 
16     <dependencies>
17         <dependency>
18             <groupId>org.springframework.boot</groupId>
19             <artifactId>spring-boot-starter</artifactId>
20         </dependency>
21 
22         <dependency>
23             <groupId>org.springframework.boot</groupId>
24             <artifactId>spring-boot-starter-test</artifactId>
25             <scope>test</scope>
26             <exclusions>
27                 <exclusion>
28                     <groupId>org.junit.vintage</groupId>
29                     <artifactId>junit-vintage-engine</artifactId>
30                 </exclusion>
31             </exclusions>
32         </dependency>
33 
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.javaqi.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 }

启动

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

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

熔断器Hystrix及服务监控Dashboard
服务雪崩效应

熔断器Hystrix及服务监控Dashboard
服务雪崩效应

指标含义:

熔断器Hystrix及服务监控Dashboard
服务雪崩效应

各种情况:

熔断器Hystrix及服务监控Dashboard
服务雪崩效应