SpringCloud 之 Hystrix 断路器,服务降级,自定义配置
Hystrix 是由 Netflix 开源的⼀个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性。Hystrix 主要通过以下几点实现延迟和容错:
依赖隔离
Spring Cloud构建微服务架构:服务容错保护(Hystrix依赖隔离)
1.引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
2.添加注释
在启动类上添加 @EnableCircuitBreaker 或 @EnableHystrix 注解开启断路器
PS:本文基于之前写的 ribbon 例子上进行代码的添加 SpringCloud 之 Ribbon
// 开启 Hystrix 断路器
@EnableCircuitBreaker
// Eureka 客户端
@EnableDiscoveryClient
@SpringBootApplication
public class Application {
// ...
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3.服务降级
关于 Feign 的 Hystrix 降级,异常拦截:SpringCloud 之 Feign 以及 Feign 异常处理
经过上面的配置 Hystrix 就已经能够正常使用了,但是当我们的请求出问题了怎么办?
继续添加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
当我们的服务出现问题导致请求无法正常响应时,Hystrix 就会对服务进行降级,这段时间这个服务的请求都会走降级逻辑,我们可以自己设计这个降级逻辑来返回我们想要的东西,这个降级的时间默认是 5s,之后又会去尝试调用主逻辑。
在这个降级逻辑中,我们既可以用它来查找问题,也可以用来返回我们所需要的提示信息
/**
* 获取信息示例
* @return
*/
// Hystrix 自定义参数使用示例
@HystrixCommand(
fallbackMethod = "fallback"
)
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String getMsg(@PathVariable("id") Integer id) throws InterruptedException {
Thread.sleep(2000);
return restTemplate.getForObject("http://service-a/getMsg", String.class);
}
/**
* 降级逻辑输出错误
* 也可以用来返回错误提示
* @return
*/
public String fallback(Integer id, Throwable throwable) {
System.out.println("id ======" + id);
System.out.println("throwable ======" + throwable);
return "fallback";
}
当然你不需要获取你请求的参数以及错误,那么这个回调就不需要参数了
4.自定义断路器
配置参考:Hystrix 配置参数全解析
经常在一些特殊情况我们需要自定义断路器,比如:报表输出 之类的需要较长时间请求的类型,因为断路器默认的 5 s,极大可能无法满足要求,可见自定义配置还是必不可少的。为此这里给出配置模板,可以参考这种格式去自定义配置:
/**
* 获取信息示例
* @return
*/
// Hystrix 自定义参数使用示例
@HystrixCommand(
fallbackMethod = "fallback",
commandProperties = {
// 方法执行超时时间,默认值是 1000,即 1 秒
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value="10000"),
// 熔断降级时间配置
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value="10000"),
},
threadPoolProperties = {
// 核心线程池的大小
@HystrixProperty(name = "coreSize", value = "1"),
// 设置队列大小为 5,默认为 -1 不启用队列
@HystrixProperty(name = "maxQueueSize", value = "1")
}
)
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String getMsg(@PathVariable("id") Integer id) throws InterruptedException {
Thread.sleep(2000);
return restTemplate.getForObject("http://service-a/getMsg", String.class);
}
5.全局配置 Hystrix
PS:这个配置 IDEA 不会出提示,所以要多检查,看看有没写错了
这种在配置文件中进行的配置在优先级上落后于注解的配置方式,因此我们可以把全局配置与注解配置混搭使用以达到想要的效果
# 全局配置 hystrix 示例
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000
我们也可以在配置文件中通过将 default 换成方法名,以此单独对某个方法进行配置
# 全局配置 hystrix 示例
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000
getMsg:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000