简介

hystrix对应的中文名字是“豪猪”,豪猪周身长满了刺,能保护自己不受天敌的伤害,代表了一种防御机制,这与hystrix本身的功能不谋而合,因此Netflix团队将该框架命名为Hystrix,并使用了对应的卡通形象做作为logo。

img

在一个分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,这个就是Hystrix需要做的事情。Hystrix提供了熔断、隔离、Fallback、cache、监控等功能,能够在一个、或多个依赖同时出现问题时保证系统依然可用。

服务雪崩效应

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

正常情况下的访问

img

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

img

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

img

作用

Hystrix断路器可以通过服务熔断和服务降级来解决上述的服务雪崩效应

使用

熔断机制是应对雪崩效应的一种微服务链路保护机制,当某个服务不可用或者响应时间超时,会进行服务降级,进而熔断该节点的服务调用,快速返回自定义的错误影响页面信息

新建Module

命名为microservice-student-provider-hystrix-1004,把microservice-student-provider-1001的配置和代码都复制一份到新建的Module中

修改pom.xml

引入Hystrix断路器依赖

1
2
3
4
5
<!--Hystrix断路器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

修改application.yml

修改server.port为1004,eureka.instance.instance-id为microservice-student-hystrix:1004

修改启动类

如果是复制过来的,重命名为StudentProviderHystrixApplication_1004,并添加@EnableCircuitBreaker注解支持Hystrix断路器

修改消费者Controller

StudentConsumerController.java在microservice-student-consumer-80项目中

添加getInfo方法,用于调用服务的getInfo方法

1
2
3
4
5
6
7
8
9
10
/**
* 获取信息
*
* @return
*/
@RequestMapping("/getInfo")
@SuppressWarnings("unchecked")
public Map<String, Object> getInfo() {
return restTemplate.getForObject(PRE_HOST + "/student/getInfo", Map.class);
}

修改提供者Controller

StudentProviderController.java在microservice-student-provider-hystrix-1004项目中

添加两个方法:getInfo方法和getInfoFallback方法

在hystrix中默认1秒算超时,使用Thread.sleep(2000)模拟请求超时(@HystrixCommand注解定义了请求超时的时候就请求getInfoFallback方法,返回500 系统出错,稍后重试),不使用就不会超时(执行完getInfo方法,返回200 业务数据)。由于请求超时的时候进行服务降级,进而熔断该节点的服务调用,快速返回自定义的错误影响页面信息,所以可以有效地解决雪崩效应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* 获取信息
*
* @return
* @throws InterruptedException
*/
@RequestMapping("/getInfo")
@HystrixCommand(fallbackMethod = "getInfoFallback")
public Map<String, Object> getInfo() throws InterruptedException {
Thread.sleep(2000);
Map<String, Object> map = new HashMap<>(16);
map.put("code", 200);
map.put("info", "业务数据");
return map;
}

/**
* 请求超时就请求我
*
* @return
*/
public Map<String, Object> getInfoFallback() {
Map<String, Object> map = new HashMap<>(16);
map.put("code", 500);
map.put("info", "系统出错,稍后重试");
return map;
}

测试

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

浏览器地址输入:http://localhost/student/getInfo

使用Thread.sleep(2000)时会超时,返回500 系统出错,稍后重试,如下图:

img

注释掉Thread.sleep(2000)时不会超时,返回200 业务数据,如下图:

img