一、断路器(Hystrix)介绍
在一个分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,这个就是Hystrix需要做的事情。Hystrix提供了熔断、隔离、Fallback、cache、监控等功能,能够在一个、或多个依赖同时出现问题时保证系统依然可用。
Netflix创造了一个调用的库Hystrix实现了断路器图案。在微服务架构中,通常有多层服务调用。
较低级别的服务中的服务故障可能导致用户级联故障。当对特定服务的呼叫达到一定阈值时(Hystrix中的默认值为5秒内的20次故障),电路打开,不进行通话。在错误和开路的情况下,开发人员可以提供后备。
开放式电路会停止级联故障,并允许不必要的或失败的服务时间来愈合。回退可以是另一个Hystrix保护的调用,静态数据或一个正常的空值。回退可能被链接,所以第一个回退使得一些其他业务电话又回到静态数据。
二、实现代码测试
创建工程结构,如图:
hystrix-client和hystrix-server的创建和SpringCloud——服务的注册与发现Eureka相同,请参考:
地址:https://blog.csdn.net/typ1805/article/details/82621881
service-hystrix-fegin和service-hystrix-ribbon的创建分别参考SpringCloud——声明性REST客户端(Feign)和SpringCloud——客户端负载平衡器(Ribbon),请参考:
地址:https://blog.csdn.net/typ1805/article/details/82633908 (feign)
https://blog.csdn.net/typ1805/article/details/82626893 (ribbon)
三、Ribbon使用断路器
1、在原来service-hystrix-ribbon工程代码的基础上,添加spring-cloud-starter-netflix-hystrix的起步依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2、启动类ServiceHystrixRibbonApplication.java添加注解@EnableHystrix来开启Hystrix,代码如下:
package com.example.demo.hystrix;
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.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableHystrix
public class ServiceHystrixRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceHystrixRibbonApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
}
3、修改Service接口,在test方法上加上@HystrixCommand注解,在方法上创建熔断器的功能,指定fallbackMethod熔断方法,熔断方法直接返回了一个字符串。代码如下:
package com.example.demo.hystrix.servcie.impl;
import com.example.demo.hystrix.servcie.TestRibbonService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
/**
* 路径:com.example.demo.hystrix.servcie.impl
* 类名:
* 功能:《用一句描述一下》
* 备注:
* 创建人:typ
* 创建时间:2018/9/12 16:16
* 修改人:
* 修改备注:
* 修改时间:
*/
@Service
public class TestRibbonServiceImpl implements TestRibbonService {
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "error")
public String test(String name) {
return restTemplate.getForObject("http://HYSTRIX-CLIENT/holle?name="+name,String.class);
}
public String error(String name){
return name+" error!";
}
}
4、启动工程进行测试,访问http://localhost:8084/test?name=张三,浏览器显示:
张三---------------8082
关闭hystrix-client 工程时,再访问http://localhost:8084/test?name=张三,浏览器会显示:
张三 error!
四、Feign使用断路器
Hystrix支持回退的概念:当电路断开或出现错误时执行的默认代码路径。要为给定的@FeignClient
启用回退,请将fallback
属性设置为实现回退的类名。
1、Feign是自带断路器的,但它没有默认打开。修改application.yml文件,添加开启断路器
feign:
hystrix:
enabled: true
2、修改Service接口,只需要在FeignClient的TestFeignService接口的注解中加上fallback的指定类就就可以,代码入下:
package com.example.demo.hystrix.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 路径:com.example.demo.hystrix.service
* 类名:
* 功能:《用一句描述一下》
* 备注:
* 创建人:typ
* 创建时间:2018/9/12 16:08
* 修改人:
* 修改备注:
* 修改时间:
*/
@FeignClient(value = "hystrix-client", fallback = TestFeignServiceFallback.class )
public interface TestFeignService {
@RequestMapping(value = "/holle",method = RequestMethod.GET)
public String getByClientOne(@RequestParam(value = "name")String name);
}
3、创建TestFeignServiceFallback.java类,需要实现TestFeignService接口,并将该类注入到spring的Ioc容器中,代码如下:
package com.example.demo.hystrix.service;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.hystrix.service.impl
* 类名:
* 功能:《用一句描述一下》
* 备注:
* 创建人:typ
* 创建时间:2018/9/12 16:41
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
public class TestFeignServiceFallback implements TestFeignService {
@Override
public String getByClientOne(String name) {
return name+" error!";
}
}
4、启动工程进行测试,访问http://localhost:8083/test?name=张三,浏览器显示:
张三--------------8082
关闭hystrix-client 工程时,再访问http://localhost:8084/test?name=张三,浏览器会显示:
张三 error!