Spring Cloud Netflix Hystrix 熔断器及仪表盘监控

Posted by 彭超 on 2019-11-05
Estimated Reading Time 7 Minutes
Words 1.8k In Total
Viewed Times

Hystrix 简介

在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以通过 RPC 相互调用,在 Spring Cloud 中可以用 RestTemplate + Ribbon 和 Feign 来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证 100% 可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet 容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的 雪崩效应

服务熔断
在微服务架构中,一个请求需要调用多个服务是非常常见的,较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值(Hystrix 默认是 5 秒 20 次) 熔断器将会被打开,为了避免连锁故障,会触发服务降级。

服务降级
Fallback 相当于是降级操作,对于查询操作, 我们可以实现一个 fallback 方法,当请求后端服务出现异常的时候,可以使用 fallback 方法返回的值,fallback 方法的返回值一般是设置的默认值或者来自缓存,告知后面的请求服务不可用了,不要再请求了。

Ribbon 中使用 Hystrix

引入依赖

在统一依赖管理项目中继承 Spring Boot 2.0.2.RELEASE 父项目,并声明 Spring Cloud Finchley.RC1 依赖版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RC1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

在当前项目 pom.xml 中主要添加依赖 spring-cloud-starter-netflix-hystrix

1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

相关配置

Application 入口类中添加 @EnableHystrix 注解开启 Hystrix

1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
public class WebAdminRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(WebAdminRibbonApplication.class, args);
}
}

Service

在业务层添加 @HystrixCommand 注解,并指定 fallbackMethod 熔断方法。当熔断器打开后,会触发相应的 fallbackMethod,也就是上面提到的服务降级

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Service
public class AdminService {

@Autowired
private RestTemplate restTemplate;

@HystrixCommand(fallbackMethod = "hiFallback")
public String sayHi(String message) {
return restTemplate.getForObject("http://hello-sring-cloud-service-admin/hi?message=" + message, String.class);
}

public String hiFallback(String message) {
return "Hi,your message is :\"" + message + "\" but request error.";
}
}

测试熔断器

此时关闭服务提供者,再次请求 http://localhost:8764/hi?message=HelloRibbon 浏览器会显示 :

1
Hi,your message is :"HelloRibbon" but request error.

Feign 中使用熔断器

在 Feign 中是自带熔断器的,但默认是关闭的,需要在配置文件中配置打开它

相关配置

application.yml 中开启熔断器

1
2
3
feign:
hystrix:
enabled: true

Application 入口类中添加 @EnableHystrix 注解开启 Hystrix

1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
public class WebAdminRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(WebAdminRibbonApplication.class, args);
}
}

Service

在业务层添加 @FeignClient 注解,并通过 fallback 属性指定 Fallback 类。当熔断器打开后,会触发该 Fallback 类中的方法,也就是服务降级。

1
2
3
4
5
6
@FeignClient(value = "hello-spring-cloud-service-admin", fallback = AdminServiceFallback.class)
public interface AdminService {

@RequestMapping(value = "hi", method = RequestMethod.GET)
public String sayHi(@RequestParam(value = "message") String message);
}

创建 Fallback 类

在 Fallback 回调类中实现对应接口,服务调用失败后,将错误提示内容返回给客户端

1
2
3
4
5
6
7
8
@Component
public class AdminServiceFallback implements AdminService {

@Override
public String sayHi(String message) {
return "Hi,your message is :\"" + message + "\" but request error.";
}
}

测试熔断器

此时再次关闭服务提供者,再次请求 http://localhost:8765/hi?message=HelloFeign 浏览器会显示:

1
Hi,your message is :"HelloRibbon" but request error.

使用熔断器仪表盘监控

RibbonFeign 项目增加 Hystrix 仪表盘监控功能,两个项目的改造方式相同,这里以 Feign 项目为例。

相关依赖

pom.xml 中添加 spring-cloud-starter-netflix-hystrix-dashboard 依赖

1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>

相关配置

Application 入口类中添加 @EnableHystrixDashboard 注解

1
2
3
4
5
6
7
8
9
@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
@EnableHystrixDashboard
public class WebAdminFeignApplication {
public static void main(String[] args) {
SpringApplication.run(WebAdminFeignApplication.class, args);
}
}

创建 HystrixDashboardConfiguration 配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
@Configuration
public class HystrixDashboardConfiguration {

@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}

启动项目,访问熔断器仪表盘页面:http://localhost:8765/hystrix.stream

Hystrix 常用配置

超时时间(默认1000ms,单位:ms)

  • hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds:在调用方配置,被该调用方的所有方法的超时时间都是该值,优先级低于下边的指定配置

  • hystrix.command.HystrixCommandKey.execution.isolation.thread.timeoutInMilliseconds:在调用方配置,被该调用方的指定方法(HystrixCommandKey 方法名)的超时时间是该值

    线程池核心线程数

  • hystrix.threadpool.default.coreSize:默认为 10

    Queue 队列

  • hystrix.threadpool.default.maxQueueSize:最大排队长度。默认 -1,使用 SynchronousQueue。其他值则使用 LinkedBlockingQueue。如果要从 -1 换成其他值则需重启,即该值不能动态调整,若要动态调整,需要使用到下边这个配置

  • hystrix.threadpool.default.queueSizeRejectionThreshold:排队线程数量阈值,默认为 5,达到时拒绝,如果配置了该选项,队列的大小是该队列

如果 maxQueueSize 等于 -1 的话,则该选项不起作用

circuitBreaker 断路器

  • hystrix.command.default.circuitBreaker.requestVolumeThreshold:当在配置时间窗口内达到此数量的失败后,进行短路。默认 20 个(10s 内请求失败数量达到 20 个,断路器开)

  • hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds:短路多久以后开始尝试是否恢复,默认 5s

  • hystrix.command.default.circuitBreaker.errorThresholdPercentage:出错百分比阈值,当达到此阈值后,开始短路。默认 50%

    fallback

  • hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests:调用线程允许请求 HystrixCommand.GetFallback() 的最大数量,默认 10。超出时将会有异常抛出,注意:该项配置对于 THREAD 隔离模式也起作用

Fallback 说明

什么情况下会触发 fallback 方法

名字 描述 触发fallback方法
EMIT (emit) 值传递 NO
SUCCESS (success) 执行完成 , 没有错误 NO
FAILURE (failure) 执行抛出异常 YES
TIMEOUT (timeout) 执行开始 , 但没有在允许的时间内完成 YES
BAD_REQUEST (bad_request) 执行抛出HystrixBadRequestException NO
SHORT_CIRCUITED (short_circuited) 断路器打开 , 不尝试执行 YES
THREAD_POOL_REJECTED (thread_pool_rejected) 线程池拒绝 , 不尝试执行 YES
SEMAPHORE_REJECTED (semaphore_rejected) 信号量拒绝 , 不尝试执行 YES

什么情况下 fallback 方法抛出异常

名字 描述 抛异常
FALLBACK_EMIT (fallback_emit) Fallback值传递 NO
FALLBACK_SUCCESS (fallback_success) Fallback执行完成 , 没有错误 NO
FALLBACK_FAILURE (fallback_failure) Fallback执行抛出出错 YES
FALLBACK_REJECTED (fallback_rejected) Fallback信号量拒绝 , 不尝试执行 YES
FALLBACK_MISSING (fallback_missing) 没有Fallback实例 YES

Hystrix Dashboard 界面监控参数

《Spring Cloud Hystrix 熔断器及仪表盘监控》


If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !