在分布式架构中,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故降服务被长时间占用不释放,避免了故障在分布式系统中的藿延。针对上述问题 ,Spring Cloud Hystrix 实现了断路器、线程隔离等一系列服务保护功能。它也是基于 Netflix 的开源框架Hystrix 实现的,该框架的目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。
Hystrix 具备:
1.服务降级
2.服务熔断
3.线程和信号隔离
4.请求缓存、请求合并以及服务监控等强大功能。
以下是实现熔断器的2中方案:
一、工厂模式实现熔断器机制
client:
@FeignClient(value = "system-redis-service1", path = "/redis", fallbackFactory = RedisRemoteClientFallbackFactory.class, configuration = RedisRemoteClient.MultipartSupportConfig.class)
public interface RedisRemoteClient {
class MultipartSupportConfig {
@Bean
public RedisRemoteClientFallbackFactory rcf()
{
return new RedisRemoteClientFallbackFactory();
}
}
/**
* 普通缓存获取
* @param key 键
* @return 值
*/
@RequestMapping(value = "/get", method = RequestMethod.POST)
String get(@RequestParam("key") String key);
/**
* 删除缓存
* @param key 可以传一个值 或多个
*/
@RequestMapping(value = "/del", method = RequestMethod.POST)
void del(@RequestParam("key") String key);
}
实现类:
@Component
public class RedisRemoteClientFallbackFactory implements FallbackFactory<RedisRemoteClient> {
@Override
public RedisRemoteClient create(final Throwable cause) {
return new RedisRemoteClient() {
@Override
public String get(String key) {
return "不好意思服务器在开小差";
}
@Override
public void del(String key) {
}
};
}
}
二、非工厂方式的熔断器实现
clinet:
@FeignClient(value = "system-redis-service", path = "/redis", fallback = RedisClientFallback.class)
public interface RedisClient {
/**
* 普通缓存获取
* @param key 键
* @return 值
*/
@RequestMapping(value = "/get", method = RequestMethod.POST)
String get(@RequestParam("key") String key);
/**
* 删除缓存
* @param key 可以传一个值 或多个
*/
@RequestMapping(value = "/del", method = RequestMethod.POST)
void del(@RequestParam("key") String key);
}
接口实现类:
@Component
public class RedisClientFallback implements RedisClient {
@Override
public String get(String key) {
return "服务器正在开小差!";
}
@Override
public void del(String key) {
}
}
项目启动类:
@SpringBootApplication
@EnableFeignClients(basePackages = {"com.xx.api"})
@EnableAsync
public class UtilsApplication {
public static void main(String[] args) {
SpringApplication.run(UtilsApplication.class, args);
}
}
配置文件开启:
feign:
hystrix:
enabled: true