一、简单使用
在fsh-substitution服务中增加Hystrix的依赖,如以下代码所示:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
在启动类上添加@EnableHystrix或者@EnableCircuitBreaker。注意,@EnableHystrix 中包含了@EnableCircuitBreaker。
然后改造之前的callHello方法,在上面增加一个@HystrixCommand注解,用于指定依赖服务调用延迟或失败时调用的方法,如以下代码所示:
@GetMapping ("/ca11Hel1o")
@HystrixCommand(fallbackMethod = "defaultCal1Hello")
public String callHe11o() {
String result = restTemplate.getForobject("http://fsh-house/house/hel1o",String.class);
return result;
}
当调用失败触发熔断时会用defaultallHello方法来回退具体的内容,定义default-CallHello方法的代码,如以下代码所示:
pub1ic String defaultCal1Hello() {
return "fail";
}
只启动fsh-substitution服务而不启动fsh-house服务,调用/alHello接口,可以看到返回的内容是"fail"。
将启动类上的@EnableHystrix去掉,重启服务,再次调用/callHello接口可以看到返回的是500错误信息,这个时候就没有用到回退功能了。
{
code: 500,
message: "I/O error on GET request for "http: //fsh-house/ house/hello":
fsh-house; nested exception is java . net . UnknownHostException:
fsh-house" ,
data: null
}
二、配置详解
HystrixCommand中除了fallbackMethod 还有很多的配置,下面我们来看看这些配置:
官方的配置信息文档请参考: github.com/Netflix/Hys… 。上面列出来的都是Hystrix的配置信息,在Spring Cloud中如何使用呢?只需要在接口的方法上面使用HystrixCommand注解( 见下面代码),指定对应的属性即可。
@HystrixCommand(fallbackMethod = "defaultcallHello",commandProperties = {
@HystrixProperty (
name= " execution. isolation. strategy",
value = "THREAD" )
}
)
@GetMapping("/cal1He1lo")
public String cal1He11o() {
String result =restTemplate .getForobject (
"http://fsh-house/house/he11o", String. class);
return result;
}
三、Feign整合Hystrix服务容错
首先需要执行第一节中的集成步骤,然后在属性文件中开启Feign 对Hystrix的支持:
feign.hystrix.enabled=true
1. Fallback 方式
在Feign的客户端类上的@FeignClient注解中指定fallback进行回退(见下面代码),改造fsh-house的客户端类HouseRemoteClient, 为其配置fallback。
@FeignClient(value = "fsh-house", . path = "/house",configuration =
FeignConfiguration.class, fallback = HouseRemoteClientHystrix.class)
public interface HouseRemoteClient{
@GetMapping("/ {houseId}")
HouseInfoDto hosueInfo (@PathVariable( "houseId" )Long houseId);
}
HouseRemoteClientHystrix类需要实现HouseRemoteClient类中所有的方法,返回回退时的内容,如以下代码所示:
@Component
pub1ic class HouseRemoteClientHystrix implements HouseRemoteClient {
@Override
public HouseInfoDto hosueInfo(Long houseId) {
return new HouseInfoDto( ) ;
}
}
启动fsh-substitution服务,停掉所有fsh-house服务,然后访问 htp://ocalhost:8082/substitution/1 接口,这个时候fsh-house服务是不可用的,必然会触发回退,返回的内容是正常的格式,只是house对象是空的,这证明回退生效了。在这种情况下,如果你的接口调用了多个服务的接口,那么只有fsh-house服务会没数据,不会影响别的服务,如果不用Hystrix回退处理,整个请求都将失败。
{
code:200,
message:"",
data: {
id:1,
money:100.12,
house: {
id :null,
city :nu1l,
region:null,
name : null
}
}
}
下面我们将启用 Hystrix 断路器禁用:
feign.hystrix.enabled=false
再次访问 http://localhost:8082/substitution/1 可以看到返回的就是500错误了,整个请求失败。
{
code:500,
message: "Failed to connect to localhost/0:0:0:0:0:0:0:1:8083 executing GET
http://fsh-house/house/1",
data:null
}
2. FallbackFactory 方式
通过fallback已经可以实现服务不可用时回退的功能,如果你想知道触发回退的原因,可以使用FallbackFactory来实现回退功能,如以下代码所示:
@Component
public class HouseRemoteClientFallbackFactory implements FallbackFactory<HouseRemoteClient> {
@Override
public HouseRemoteClient create( final Throwable cause) {
return new HouseRemoteClient() {
@Override
public HouseInfoDto hosueInfo(Long houseId) {
HouseInfoDto info = new HouseInfoDto( );
info. setData (new HouseInfo(1L, "", "", cause . getMessage()));
return info;
}
};
}
}
FallbackFactory的使用就是在@FeignClient中用fallbackFactory 指定回退处理类,如以下代码所示:
@FeignClient (value = "fsh-house",path = "/house”
configuration = FeignConfiguration.class,
fallbackFactory = HouseRemoteClientFallbackFactory.class)
在这个回退处理的时候,将异常信息设置到HouseInfo中的name属性中了,我们重启fsh-substitution,调用接口,可以看到异常信息返回在结果里面了,FallbackFactory 和 Fallback 唯一的区别就在这里。
四、Feign 中禁用 Hystrix
禁用Hystrix还是比较简单的,目前有两种方式可以禁用,其中一种是在属性文件中进行全部禁用。
feign.hystrix.enabled=false
另一种是通过代码的方式禁用某个客户端,在Feign的配置类中增加代码,如以下代码所示:
@Configuration
public class FeignConfiguration {
@Bean
@Scope("prototype" )
public Feign. Builder feignBuilder() {
return Feign.builder();
}
}