在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以通过 RPC
相互调用.为了保证其高可用,单个服务通常会集群部署.由于网络原因或者自身的原因,服务并不能保证 100% 可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet
容器的线程资源会被消耗完毕,导致服务瘫痪.服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的 “雪崩” 效应.
为了解决这个问题,业界提出了熔断器模型
Netflix 开源了 Hystrix 组件,实现了熔断器模式.Spring Cloud 对这一组件进行了整合,在微服务架构中,一个请求需要调用多个服务是非常常见的.
较底层的服务如果出现故障,会导致连锁故障.当对特定的服务的调用的不可用达到一个阈值(Hystrix 是 5 秒 20 次)熔断器将会被打开.熔断器打开后,为了避免连锁故障,通过 fallback
方法可以直接返回一个固定值.
2.1 在 pom.xml
中增加依赖
org.springframework.cloud
spring-cloud-starter-netflix-hystrix
2.0.1.RELEASE
2.2 在 Application 中增加 @EnableHystrix
注解
package com.syc.dubbo.service;
import com.alibaba.dubbo.container.Main;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@EnableHystrix
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
// 启动 Provider 容器,注意这里的 Main 是 com.alibaba.dubbo.container 包下的.
Main.main(args);
}
}
2.3 在 Service 中增加 @HystrixCommand
注解
在调用方法上增加 @HystrixCommand
配置,此时调用会经过 Hystrix 代理.
package com.syc.dubbo.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.utils.FallbackMethod;
import com.syc.dubbo.service.user.UserService;
import org.springframework.beans.factory.annotation.Value;
/**
* 接口实现类
*/
@Service(version = "${user.service.version}")
public class UserServiceImpl implements UserService {
@Value("${dubbo.protocol.port}")
private String port;
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
})
@Override
public String sayHi() {
//return "Hello Dubbo"+port;
//人为制造一个异常
throw new RuntimeException("Exception happending.....");
}
}
2.4 测试熔断器
此时我们再次请求服务提供者,浏览器会报 500 异常.
Exception happending.....
3. Dubbo Consumer 中使用熔断器
3.1 在 pom.xml
中增加依赖
org.springframework.cloud
spring-cloud-starter-netflix-hystrix
2.0.1.RELEASE
3.2 在 Application 中增加 @EnableHystrix
注解
package com.syc.dubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@EnableHystrix
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
3.3 在调用方法上增加 @HystrixCommand
注解,并指定 fallbackMethod
方法
package com.syc.dubbo.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.syc.dubbo.service.user.UserService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
*
*/
@RestController
public class UserController {
@Reference(version = "${user.service.version}")
private UserService userService;
@HystrixCommand(fallbackMethod = "hiError")
@RequestMapping(value = "hi")
public String sayHi() {
return userService.sayHi();
}
//远程调用失败时执行的回调方法.
public String hiError() {
return "Hystrix fallback method";
}
}
3.4 测试熔断器
此时我们再次请求服务提供者,浏览器会显示:
Hystrix fallback method

至此,Dubbo + Hystrix 配置完成
二. Dubbo + Hystrix 熔断器仪表盘 1. 使用熔断器仪表盘监控在 Provider 和 Consumer 项目增加 Hystrix 仪表盘功能,两个项目的改造方式相同,此处不写那么多代码.
2. 在pom.xml
中增加依赖
org.springframework.cloud
spring-cloud-starter-netflix-hystrix-dashboard
2.0.1.RELEASE
3. 在 Application 中增加 @EnableHystrixDashboard
注解
package com.syc.dubbo.service;
import com.alibaba.dubbo.container.Main;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@EnableHystrix
@EnableHystrixDashboard
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
// 启动 Provider 容器,注意这里的 Main 是 com.alibaba.dubbo.container 包下的.
Main.main(args);
}
}
4. 创建 hystrix.stream
的 Servlet 配置
Spring Boot 2.x 版本开启 Hystrix Dashboard 与 Spring Boot 1.x 的方式略有不同,需要增加一个 HystrixMetricsStreamServlet
的配置,代码如下:
package com.syc.dubbo.config;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
*Spring Boot 2.x 版本开启 Hystrix Dashboard 与 Spring Boot 1.x 的方式略有不同,
* 需要增加一个 HystrixMetricsStreamServlet 的配置.
*/
@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;
}
}
5. 测试 Hystrix Dashboard
浏览器端访问 http://localhost:9090/hystrix 界面如下:
点击 Monitor Stream,进入下一个界面,访问 http://localhost:9090/hi 触发熔断后,输入http://localhost:9090/hystrix.stream,然后点击Monitor Stream按钮,监控界面显示效果如下:
6.1 什么情况下会触发 fallback
方法
6.2 fallback
方法在什么情况下会抛出异常
6.3 Hystrix Dashboard 界面监控参数

6.4 Hystrix 常用配置信息
6.4.1 超时时间(默认1000ms,单位:ms)
-
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds
: 在调用方配置,被该调用方的所有方法的超时时间都是该值,优先级低于下边的指定配置. -
hystrix.command.HystrixCommandKey.execution.isolation.thread.timeoutInMilliseconds
: 在调用方配置,被该调用方的指定方法(HystrixCommandKey 方法名)的超时时间是该值.
6.4.2 线程池核心线程数
hystrix.threadpool.default.coreSize
: 默认为 10
6.4.3 Queue
-
hystrix.threadpool.default.maxQueueSize
: 最大排队长度.默认 -1,使用SynchronousQueue
,其他值则使用LinkedBlockingQueue
.如果要从 -1 换成其他值则需重启,即该值不能动态调整,若要动态调整,需要使用到下边这个配置. -
hystrix.threadpool.default.queueSizeRejectionThreshold
: 排队线程数量阈值,默认为 5,达到时拒绝,如果配置了该选项,队列的大小是该队列.
注意: 如果 maxQueueSize=-1
的话,则该选项不起作用.
6.4.4 断路器
-
hystrix.command.default.circuitBreaker.requestVolumeThreshold
:当在配置时间窗口内达到此数量的失败后,进行短路,默认 20 个(10s 内请求失败数量达到 20 个,断路器开). -
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds
:短路多久以后开始尝试是否恢复,默认 5s -
hystrix.command.default.circuitBreaker.errorThresholdPercentage
:出错百分比阈值,当达到此阈值后,开始短路,默认 50%.
6.4.5 fallback
hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests
:调用线程允许请求HystrixCommand.GetFallback()
的最大数量,默认 10,超出时将会有异常抛出,注意:该项配置对于 THREAD 隔离模式也起作用.
6.4.6 属性配置参数
-
参数说明: https://github.com/Netflix/Hystrix/wiki/Configuration
-
HystrixProperty 参考代码: http://www.programcreek.com/java-api-examples/index.php?source_dir=Hystrix-master/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/common/configuration/command/BasicCommandPropertiesTest.java