SpringCloud之断路器Hystrix

一、Hystrix是什么

之前文章讲过,SpringCloud中加入了断路器功能,当请求接口时,服务提供者出现宕机问题,没有一个好的容错机制的情况下,是有可能造成雪崩效应,造成整个服务瘫痪,从而导致系统挂掉。Hystrix是Netflix提供的一个延迟和容错库,可以在服务出现问题时,进行及时的容错处理。

雪崩效应,又称级联故障,服务A为服务提供者,服务B为A的服务消费者,当A不可用时,造成B不可用,而B是服务C和D的服务提供者,最终又导致服务C和D不可用,这种“基础故障”导致的级联故障称为雪崩效应,如下图

二、SpringCloud整合Hystrix进行容错

1.搭建SpringCloud工程,创建消费者和服务者,可参考之前的帖子,点我进去

2.在服务消费者端项目的pom.xml文件中加入如下依赖

1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

3.在服务消费者端启动类上加入@EnableHystrix 注解,来开启Hystrix容错

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
package org.consumer.user;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.client.RestTemplate;
@ComponentScan("org.consumer")
@EnableDiscoveryClient//开启发现服务功能
@SpringBootApplication
@EnableHystrix
public class ConsumerApplication {

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

@LoadBalanced//开启负载均衡机制
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
// 用来发送http请求
}
}

4.在服务消费者端,控制器请求方法加上容错的处理方法,使用@HystrixCommand(fallbackMethod = “method”) 注解,出错后将调用指定的失败回调方法。

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
28
29
30
31
32
33
34
35
36
37
38
39
package org.consumer.control;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

/**
* @author yzx96
*
*/
@RestController
public class UserController {

@Autowired
RestTemplate restTemplate;

/**
* 购买方法
* @param name
* @return
*/
@GetMapping("/buy")
@HystrixCommand(fallbackMethod = "failInfo")
public String butTicket(String name){
String s = restTemplate.getForObject("http://PROVIDER-TICKET/ticket/", String.class);
return name+"购买了"+s;
}
/**
* 失败回调
* @param name
* @return
*/
public String failInfo(String name) {
return name+"没有购买成功";
}
}

5.正常启动eureka-server,启动服务提供者和消费者,测试是否可以正常使用,eureka显示两个工程启动正常

6.测试服务消费端接口,显示调用服务正常

7.我们将服务提供者工程,进行关闭,再次测试,测试结果表明,调用服务提供者失败时,Hystrix调用了失败回调方法来处理。

三、Hystrix容错机制分析

1.Hystrix的容错机制使用了Spring的面向切面的方式进行处理,在HystrixCommandAspect.java文件中可以看到定义的切面,使用了@Aspect注解,使用了@HystrixCommand注解时,调用了hystrixCommandAnnotationPointcut()方法,同样又使用了@Around切入在执行hystrixCommandAnnotationPointcut()方法时,执行methodsAnnotatedWithHystrixCommand方法,来执行开发者参数传入的方法。

2.再来看methodsAnnotatedWithHystrixCommand方法,最终是通过CommandExecutor.execute来执行指定的方法。

3.跳转到CommandExecutor.execute方法可以看到,都是使用了castToExecutable方法,将HystrixExecutable进行转换

4.通过查看可以看到HystrixExecutable的实现类有很多,但是只有GenericCommand含有getFallback()方法。

5.getFallback方法首先会对是否设置了commandAction进行判断,commandAction就是我们之前所设置的fallback字段指向的方法 ,满足条件会进入process方法

6.进入process方法,如果没有设置失败处理方法则调用父类HystrixCommand的getFallBack()方法,父类的getFallBack方法会抛出一个找不到方法的异常,代码如下:

7.在这里定义了很多种执行失败的情况,根据不同的情况会进入不同的处理方法,最终这些处理方法都会调用HystrixCommand.java中的getFallbackObservable()方法,并最终进入上文配置的真正执行fallback方法的代码。

四、总结

其实Hystrix的容错机制使用了Spring的面向切面,在日常开发中,我们也可尝试使用基础的东西去搭建或者处理指定的业务,来完善日常开发使用,也可以从这些开源框架的原理中读出他的思维模式,进行学习。