Hystrix 是由 Netflix 开源的一个延迟和容错库
本文中涉及到的 Spring Cloud 内容,可以查看我的相关博客
使用的 Hystrix 版本为1.4.3
消费端导入 hystrix 依赖( 2.0+版本和1+版本使用方法不同,本文使用1.4.3版本)
// compile('org.springframework.cloud:spring-cloud-starter-hystrix')
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-hystrix', version: '1.4.3.RELEASE'
启动类上添加注解(以下两个均可)
// @EnableCircuitBreaker
@EnableHystrix
在需要熔断回退的方法上添加注解,并写回退方法
@HystrixCommand(fallbackMethod = "findByIdFallback")//fallbackMethod=回退时执行的方法
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id){
return this.restTemplate.getForObject("http://microservice-provider-user/user/"+id,User.class);
}
//回退时执行的方法
public User findByIdFallback(Long id){
User user=new User();
user.setId(-1L);
user.setName("默认用户");
return user;
}
最后,启动服务端、客户端和本消费端。然后关闭客户端,访问得到的数据就是回退方法中“默认用户”
简单来说,Hystrix 有两种隔离策略:线程隔离、信号量隔离:
- THREAD(线程隔离),使用该方式,HystrixCommand 将会在单独的线程上执行,并发送请求收线程池总线程数量的限制
- SEMAPHORE(信号量隔离),使用该方式,HystrixCommand 将会在调用线程上执行,开销相对较小,并发请求受信号量个数的限制
使用以下配置指定隔离策略
execution.isolation.strategy
Hystrix 默认的隔离策略是 THREAD。正常情况下,保持默认就好,如果发生找不到上下文的运行异常,可考虑将隔离策略设置为 SEMAPHORE
Feign 中自带 Hystrix,所以请暂时将 Hystrix 相关导入注释掉(依赖、启动类注解、方法上的HystrixCommand注解)
在相对较旧的版本中,Feign 客户端的 Hystrix 是默认开启的。而相反,最近版本的 Hystrix 默认是关闭的。使用 feign.hystrix.enable=true 来开启,或 =false 来关闭
Feign 中使用 Hystrix 很简单,在 FeignClient 中添加 fallback 属性、写回退类
@FeignClient(name = "microservice-provider-user",configuration = FeignConfiguration.class,fallback = FeignClientFallback.class)
@Service
public interface UserFeignClient {
@GetMapping("user/{id}")
User findById(@PathVariable("id") Long id);
}
@Component
class FeignClientFallback implements UserFeignClient{
@Override
public User findById(Long id) {
User user=new User();
user.setId(-1L);
user.setName("默认用户");
return user;
}
}
结果和第一节中相同
也可以通过 fallback factory 查找回退原因。将 fallback 改为 fallbackFactory,写回退工厂类
@FeignClient(name = "microservice-provider-user",configuration = FeignConfiguration.class,fallbackFactory = FeignClientFallbackFactory.class)
@Service
public interface UserFeignClient {
@GetMapping("user/{id}")
User findById(@PathVariable("id") Long id);
}
@Component
class FeignClientFallbackFactory implements FallbackFactory{
private static final Logger LOGGER = LoggerFactory.getLogger(FeignClientFallbackFactory.class);
@Override
public UserFeignClient create(Throwable cause) {
return new UserFeignClient() {
@Override
public User findById(Long id) {
FeignClientFallbackFactory.LOGGER.info("fallback; reason was:",cause);
User user=new User();
user.setId(-1L);
user.setName("默认用户");
return user;
}
};
}
}
fallbackFactory 还有其他用途,例如使不同的异常返回不同的回退结果:
@Component
class FeignClientFallbackFactory implements FallbackFactory<UserFeignClient>{
private static final Logger LOGGER = LoggerFactory.getLogger(FeignClientFallbackFactory.class);
@Override
public UserFeignClient create(Throwable cause) {
return new UserFeignClient() {
@Override
public User findById(Long id) {
User user=new User();
if(cause instanceof IllegalArgumentException){
user.setId(-1L);
}else{
user.setId(-2L);
}
return user;
}
};
}
}
结果请自行检测
导入 actuator 依赖
compile 'org.springframework.boot:spring-boot-starter-actuator'
据书上说,Actuator 的 /health 端点可以检测到 Hystrix,但博主亲测并没有(可能是版本问题)
Actuator /hystrix.stream 端口在消费端有访问活动之后会重复出现 HystrixCommand名称、group名称、熔断器状态、错误率等信息
2.0版本
management:
server:
port: 8011 #Actuator访问端口
address: 127.0.0.1 #Actuator访问者
endpoints:
enabled-by-default: true #设置所有端点可访问
web:
base-path: / #指定actuator访问路径,默认是/actuator
1.x 版本(默认所有端口开放)
management:
address: 127.0.0.1
port: 8011
导入 dashborad 依赖
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-hystrix-dashboard', version: '1.4.3.RELEASE'
启动类添加注解
@EnableHystrixDashboard
启动项目后访问 http://localhost:8010/user/1
产生访问数据,然后访问 http://localhost:8010/hystrix
可看到 Hystrix Dashboard 主页
URL填入 http://localhost:8010/hystrix.stream
,Title 随意设置。点击 Moniter Stream 按钮后看到各项指标检测界面
对于 1.4.3 左右的版本来说,可能是因为版本的原因造成以上问题,此时需要在被监控程序中增加以下代码来解决
@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;
}
如果项目使用了 Feign ,以下配置一定要是 true,否则 Feign 通道的数据将不会被检测到,会一直显示 Loading
feign.hystrix.enable = true
且,Hystrix_Dashborad 不要与其整合在一起,否则即便以上配置开启,也检测不到 Feign 通道数据
所以,使用 Feign 的情况下,正确做法是开启以上配置,然后让 Dashboard 成为独立的项目
以上分别是一般通道和 Feign 通道的监控数据
以上的代码大多数经过我的测试
引用内容源自 《Spring Cloud与Docker微服务架构实战》/周立 著