一、Hystrix简介
Hystrix是Netflix开源的一款容错框架,包含常用的容错方法:线程隔离、信号量隔离、降级策略、熔断技术。在高并发访问下,系统所依赖的服务的稳定性对系统的影响非常大,依赖有很多不可控的因素,比如网络连接变慢,资源突然繁忙,暂时不可用,服务脱机等。我们要构建稳定、可靠的分布式系统,就必须要有这样一套容错方法。
本篇文章基于前一篇文章的工程
二:使用Feign调用服务中使用Hystrix
首先要导入pom依赖
假如你的SpringBoot的版本是2.0以下的版本,那么pom文件当中只需要导入如下依赖:
<!--spring-cloud-starter-hystrix的起步依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
假如你的版本是SpringBoot2.0+的版本,那么,我们需要导入的pom依赖如下,否则会出现找不到类的情况,比如出现@HystrixCommand找不到类的情况。
<!--spring-cloud-starter-hystrix的起步依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>RELEASE</version>
</dependency>
Feign是自带断路器的,但是它没有默认打开。需要在配置文件中配置打开它,在application.yml文件中加以下代码:
#feign.hystrix.enabled=true
feign:
hystrix:
enabled: true
原来我们调用服务只需要写一个接口,但是现在我们需要在接口上进行改造
@FeignClient(value = "mall-wechatservice",fallback = HelloServiceHystrix.class)
public interface HelloServiceRestful {
/**
* 请求mall_wechatservice模块的helloA
* @return
*/
@RequestMapping("/helloA")
public String getInfoFromWechatA();
/**
* 请求mall_wechatservice模块的helloB
* @return
*/
@RequestMapping("/helloB")
public String getInfoFromWechatB(@RequestBody String json);
/**
* 请求mall_wechatservice模块的helloC
* @return
*/
@RequestMapping("/helloC")
public String getInfoFromWechatC(@RequestBody Map<String, Object> params);
}
fallback=xxx.class,这个class就是基于这个接口的实现类
@Component
public class HelloServiceHystrix implements HelloServiceRestful{
@Override
public String getInfoFromWechatA() {
return "sorry,errorgetInfoFromWechatA";
}
@Override
public String getInfoFromWechatB(String json) {
return "sorry,errorgetInfoFromWechatB";
}
@Override
public String getInfoFromWechatC(Map<String, Object> params) {
return "sorry,errorgetInfoFromWechatC";
}
}
我们基于这个接口有一个实现类,并且我们打开了熔断机制,当服务器检测到服务无法正常执行之后,就会返回这个方法里面的返回值。我们先正常开启服务,然后再关闭服务,可以看到打印的信息如下:说明刚开始正常返回,关闭服务之后按照我们事先的方法返回。
三:使用RestTemplate调用服务中使用Hystrix
首先按照上一步的要求导入pom文件
在主类上加@EnableHystrix注解开启Hystrix
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableEurekaClient
@SpringBootApplication
@EnableFeignClients
@EnableHystrix
public class MallManagerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(MallManagerServiceApplication.class, args);
}
}
在Mall_ManagerService模块中编写服务调用方法,调用Mall_WechatService里面的三个服务。我们可以看到方法上加上了@HystrixCommand注解。该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法。
@Service
public class HelloService {
private final Logger logger= LoggerFactory.getLogger(this.getClass());
@Autowired
private RestTemplate restTemplate;
String host = "http://mall-wechatservice";
@HystrixCommand(fallbackMethod = "hystrixError")
public String hystrix() {
String url = host+"/helloA";
String text = restTemplate.getForObject(url,String.class);
logger.info("接口正常返回的信息是:"+text);
return text;
}
public String hystrixError() {
logger.info("服务已经发生了中断了");
return "sorry,error!";
}
}
在Controller当中使用该类去调用服务
@Controller
public class HelloController {
private final Logger logger= LoggerFactory.getLogger(this.getClass());
@Autowired
private HelloService helloService;
@ResponseBody
@RequestMapping("/sayHelloAA")
public String getFromWechatA(){
String text = helloService.hystrix();
return text;
}
}
我们先正常开启Mall_WechatService和Mall_ManagerService,请求/sayHelloAA,然后再关闭Mall_WechatService服务,再请求一次/sayHelloAA,可以看到控制台打印如下信息:第一次正常返回,第二次提示出现了服务中断。