一、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(); } }
|
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;
@RestController public class UserController {
@Autowired RestTemplate restTemplate;
@GetMapping("/buy") @HystrixCommand(fallbackMethod = "failInfo") public String butTicket(String name){ String s = restTemplate.getForObject("http://PROVIDER-TICKET/ticket/", String.class); return name+"购买了"+s; }
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的面向切面,在日常开发中,我们也可尝试使用基础的东西去搭建或者处理指定的业务,来完善日常开发使用,也可以从这些开源框架的原理中读出他的思维模式,进行学习。
