一、初识Hystrix
Hystrix [hɪst'rɪks],中文含义是豪猪,因其背上长满棘刺,从而拥有了自我保护的能力。本文所说的Hystrix是Netflix开源的一款容错框架,同样具有自我保护能力。为了实现容错和自我保护,下面我们看看Hystrix如何设计和实现的。
Hystrix设计目标:
- 对来自依赖的延迟和故障进行防护和控制——这些依赖通常都是通过网络访问的
- 阻止故障的连锁反应
- 快速失败并迅速恢复
- 回退并优雅降级
- 提供近实时的监控与告警
Hystrix⽤于隔离访问远程系统、服务或者第三⽅库,防⽌级联失败,从⽽提升系统的可⽤性与容错性。Hystrix主要通过以下⼏点实现这些设计目标,主要包括延迟和容错。
- 包裹请求:使⽤HystrixCommand或HystrixObservableCommand包裹对依赖的调⽤逻辑(切面增强的原理)
- 跳闸机制:当某服务的错误率超过⼀定的阈值时,Hystrix可以跳闸,停⽌请求该服务⼀段时间
- 资源隔离:Hystrix为每个依赖都维护了⼀个⼩型的线程池(舱壁模式)(或者信号量)。如果该线程池已满, 发往该依赖的请求就被⽴即拒绝,⽽不是排队等待,从⽽加速失败判定
- 监控:Hystrix可以近乎实时地监控运⾏指标和配置的变化,例如成功、失败、超时、以及被拒绝的请求等
- 回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执⾏回退逻辑。回退逻辑由开发⼈员⾃⾏提供,例如返回⼀个缺省值
- ⾃我修复:断路器打开⼀段时间后,会⾃动进⼊“半开”状态
二、应用
1、引入pom依赖
由于父项目中已经引入了SpringCloud依赖的版本管理,所以我这里只引入没有指定version属性,如果你的项目中没有版本管理需要单独引入version属性.
<!--熔断器Hystrix--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <!--<version> 2.0.2.RELEASE</version>--> </dependency>
2、引入pom依赖之后需要在启动类上开启熔断器
注解介绍如果仅仅需要是一个熔断使用@EnableCircuitBreaker即可
@EnableDiscoveryClient 注解声明启动Ribbon负载
@EnableHystrix 标识使用Hystrix,在SpringBoot2.x版本后也可以省略掉
@EnableCircuitBreaker 标识开启熔断器
@SpringCloudApplication 注解等同与同属引入@SpringBootAppliction + @EnableDiscoveryClient + @EnableCircuitBreaker注解
/** * @author niunafei * @function * @email niunafei0315@163.com * @date 2020/9/2 6:11 PM * <p> * 注解简化写法 * @SpringCloudApplication = @SpringBootApplication + @EnableDiscoveryClient + @EnableCircuitBreaker */ @SpringBootApplication @EnableDiscoveryClient @EnableHystrix @EnableCircuitBreaker //@SpringCloudApplication public class AutodeliverApplication { public static void main(String[] args) { SpringApplication.run(AutodeliverApplication.class, args); } /** * 注⼊RestTemplate * LoadBalanced开启ribbon * * @return */ @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } }
3、调取客户端进行配置使用
多个参数说明,具体概念参考-->这里
代码硬编码如下,应用于单个接口,这里存在跳闸与自我修复机制、线程池(舱壁模式)、服务降级。
// 使⽤@HystrixCommand注解进⾏熔断控制 @HystrixCommand( // 线程池标识,仓壁模式的应用,每一个标识独立线程池,要保持标识唯⼀,不唯⼀的话就共⽤了 threadPoolKey = "findResumeOpenState", // 线程池细节属性配置 threadPoolProperties = { @HystrixProperty(name = "coreSize", value = "1"), // 线程数,默认10个线程 @HystrixProperty(name = "maxQueueSize", value = "20") // 等待队列⻓度 }, // commandProperties熔断的⼀些细节属性配置 commandProperties = { // 每⼀个属性都是⼀个HystrixProperty,HystrixCommandProperties可以获取配置信息 //服务降级,设置超时时间2秒 @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000"), //以下配置是熔断跳闸与自我修复:8秒钟内,请求次数达到2个,并且失败率在50%以上,就跳闸,跳闸后活动窗⼝设置为3s,即三秒后进行重试 //统计时间窗口定义 @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds",value = "8000"), //最小请求数量 @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "2"), //统计时间框口内的异常百分比 @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50"), //自我修复活动窗口时长 @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "3000") }, //异常返回方法,也是服务降级,方法的入参和返回值与该方法一致,在类上@DefaltProperties(defaultFallback="fallback")注解是为全类指定降级回调方法 fallbackMethod = "fallback" ) @GetMapping("/checkState/{userId}") public String findResumeOpenState(@PathVariable Long userId) { //发起调用 Long start = System.currentTimeMillis(); Integer forObject = restTemplate.getForObject("http://city-service-resume/resume/openstate/" + userId, Integer.class); System.out.println("======>>>调⽤微服务,获取到⽤户" + userId + "的默认 当前状态为:" + forObject); return forObject + " ,响应时间" + (System.currentTimeMillis() - start); } /** * 降级返回值 * * @param userId * @return */ public String fallback(Long userId) { return -1 + " ,响应时间" + (System.currentTimeMillis() - System.currentTimeMillis()); }
全局配置如下(仅仅适用于commandProperties内的属性配置):改配置应用于全局HystrixCommand注解
# 配置熔断策略:
hystrix:
command:
default:
circuitBreaker:
# 强制打开熔断器,如果该属性设置为true,强制断路器进⼊打开状态,将会拒绝所有的请求。 默认false关闭的
forceOpen: false
# 触发熔断错误⽐例阈值,默认值50%
errorThresholdPercentage: 50
# 熔断后休眠时⻓,默认值5秒
sleepWindowInMilliseconds: 3000
# 熔断触发最⼩请求次数,默认值是20
requestVolumeThreshold: 2
execution:
isolation:
thread:
# 熔断超时设置,默认为1秒
timeoutInMilliseconds: 2000
提示:简单测试熔断器的状态(是否被熔断),方式通过SpringBoot的健康检查接口即可。需要:
第一步配置开启健康检查(如下)
第二步然后访问http://ip:端口/actuator/health接口
第三步查看返回json的hystrix属性。
# springboot中暴露健康检查等断点接⼝
management:
endpoints:
web:
exposure:
include: "*"
# 暴露健康接⼝的细节
endpoint:
health:
show-details: always
三、监控
上面链接监控仪表盘需要注意的点:
1、正常配置springCloud的配置文件,包括应用名称与Eureka的注册中心等配置
2、上面使用的spring原生xml配置方式,在springboot中被监控的应用添加以下Bean对象配置即可
@Bean public ServletRegistrationBean getServlet(){ HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); //启动状态 registrationBean.setLoadOnStartup(1); //mvc访问路径 registrationBean.addUrlMappings("/actuator/hystrix.stream"); //bean名称 registrationBean.setName("HystrixMetricsStreamServlet"); return registrationBean; }