一、hystrix是什么?
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比 如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分 布式系统的弹性。
“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
总体来说
[Hystrix]
就是一个能进行熔断和降级的库,通过使用它能提高整个系统的弹性。
1.1、说明实例
在微服务架构里,一个系统会有很多的服务。以场景的电商订单服务业务场景为例:订单服务在一个业务流程里需要调用三个服务。现在假设订单服务自己最多只有100个线程可以处理请求,然后呢,积分服务不幸的挂了,每次订单服务调用积分服务的时候,都会卡住几秒钟,然后抛出—个超时异常。
咱们一起来分析一下,这样会导致什么问题?
-
如果系统处于高并发的场景下,大量请求涌过来的时候,订单服务的100个线程都会卡在请求积分服务这块。导致订单服务没有一个线程可以处理请求
-
然后就会导致别人请求订单服务的时候,发现订单服务也挂了,不响应任何请求了
上面这个,就是微服务架构中恐怖的服务雪崩问题,如下图所示:
如上图,这么多服务互相调用,要是不做任何保护的话,某一个服务挂了,就会引起连锁反应,导致别的服务也挂。比如积分服务挂了,会导致订单服务的线程全部卡在请求积分服务这里,没有一个线程可以工作,瞬间导致订单服务也挂了,别人请求订单服务全部会卡住,无法响应。
但是我们思考一下,就算积分服务挂了,订单服务也可以不用挂啊!为什么?
-
我们结合业务来看:支付订单的时候,只要把库存扣减了,然后通知仓库发货就OK了
-
如果积分服务挂了,大不了等他恢复之后,慢慢人肉手工恢复数据!为啥一定要因为一个积分服务挂了,就直接导致订单服务也挂了呢?不可以接受!
这里我们就可以使用Hystrix,实现微服务的隔离、熔断以及降级。
打个比方:现在很不幸,积分服务挂了,会咋样?
当然会导致订单服务里的那个用来调用积分服务的线程都卡死不能工作了啊!但是由于订单服务调用库存服务、仓储服务的这两个线程池都是正常工作的,所以这两个服务不会受到任何影响。
这个时候如果别人请求订单服务,订单服务还是可以正常调用库存服务扣减库存,调用仓储服务通知发货。只不过调用积分服务的时候,每次都会报错。但是如果积分服务都挂了,每次调用都要去卡住几秒钟干啥呢?有意义吗?当然没有!所以我们直接对积分服务熔断不就得了,比如在2分钟内请求积分服务直接就返回了,不要去走网络请求卡住几秒钟,这个过程,就是所谓的熔断!
那人家又说,兄弟,积分服务挂了你就熔断,好歹你干点儿什么啊!别啥都不干就直接返回啊?没问题,咱们就来个降级:每次调用积分服务,你就在数据库里记录一条消息,说给某某用户增加了多少积分,因为积分服务挂了,导致没增加成功!这样等积分服务恢复了,你可以根据这些记录手工加一下积分。这个过程,就是所谓的降级。
为帮助大家更直观的理解,接下来用一张图,梳理一下Hystrix隔离、熔断和降级的全流程:
二、实战
2.1、降级,超时实现
我们先来解释一下降级,降级是当我们的某个微服务响应时间过长,或者不可用了,讲白了也就是那个微服务调用不 了了,我们不能吧错误信息返回出来,或者让他一直卡在那里,所以要在准备一个对应的策略(一个方法)当发生 这种问题的时候我们直接调用这个方法来快速返回这个请求,不让他一直卡在那 。
讲了这么多,我们来看看具体怎么操作:
我们刚刚说了某个微服务调用不了要做降级,也就是说,要在调用方做降级(不然那个微服务都down掉了再做 降级也没什么意义了) 比如说我们 user 调用order那么就在user 做降级。
2.1.1、引入依赖
先把hystrix的依赖加入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2.1.2、启动类、代码
启动类加入注解@EnableHystrix 或者@EnableCircuitBreaker(他们之间是一个继承关系,2个注解所描述的内容是 完全一样的,可能看大家之前都是EnableXXX(比如eureka)这里专门再写一个EnableHystrix方便大家记吧)
@SpringBootApplication
@EnableEurekaClient
//@RibbonClients({
// @RibbonClient(name = "SERVER-ORDER",configuration = OrderRuleConfig.class),
// @RibbonClient(name = "SERVER-POWER",configuration = PowerRuleConfig.class)
//})
//配置 不同的微服务 不同的负载均衡策略
@RibbonClients({
@RibbonClient(name = "SERVER-ORDER",configuration = OrderRuleConfig.class)
})
@EnableFeignClients //声明式调用
@EnableHystrix //hystrix 限流、降级、熔断
public class UserApp {
public static void main(String[] args) {
SpringApplication.run(UserApp.class);
}
}
然后在我们的controller上面加入注解@HystrixCommand(fallbackMethod就是我们刚刚说的方法的名字)
/**
* 获取订单信息
* @param name
* @return
*/
@GetMapping("/getOrder.do")
@HystrixCommand(fallbackMethod = "fallbackMethod")
public R getOrder(@RequestParam String name){
//调用订单系统
Object object = restTemplate.getForObject(ORDER_URL+"/getOrder.do?name="+name,Object.class);
return R.success("操作成功",object);
}
fallbackMethod: 这个R不重要,你看做一个Map就好了, 是我封装的一个返回值的类。
public R fallbackMethod(String name){
System.out.println(name);
return R.error("调用order服务出现问题,降级信息");
}
这里的这个降级信息具体内容得根据业务需求来, 比如说返回一个默认的查询信息,亦或是系统维护(因为有可能 要暂时关闭某个微服务而吧资源让给其他服务)等等...
我们在order代码里面模拟一个异常 当参数为 name 为"8848"的时候,休眠1.5s在返回。
@GetMapping("/getOrder.do")
public Object getOrder(@RequestParam("name") String name){
Map<String,Object> map = new HashMap<>();
//当名字为降级的时候 开始增加休眠时间
if(name.equals("8848")){
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
map.put("order00","用户名:"+name +"购买了一个 渣渣乐");
return map;
}
然后启动服务调用一下看看结果,如果name是 8848降级,其他则不降级,这里是模拟使用。
可能有些同学有疑问, 我这里什么都没干, 就让他休眠了一下 , 怎么就知道我这里超时了呢?
因为hystrix他有默认的超时监听,当你这个请求默认超过了1秒钟就会超时 当然,这个可以配置的
讲了这么多, 这个降级到底有什么用呢?
第一, 他可以监听你的请求有没有超时,第二,报错了他这里直接截断了没有让请求一直卡在这里
其实降级还有一个好处, 就是当你的系统马上迎来大量的并发(双十一秒杀这种 或者促销活动) 这时候如果发现系 统马上承载不了这么大的并发时, 可以考虑先关闭一些不重要的微服务(在降级方法里面返回一个比较友好的信 息),吧资源让给主微服务,总结一下就是 整体资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开启回来。
2.2、熔断,限流
熔断
讲完降级,我们来讲讲熔断,其实熔断,就好像我们生活中的跳闸一样, 比如说你的电路出故障了,为了防止出现大型事故 这里直接切断了你的电源以免意外继续发生, 把这个概念放在我们程序上也是如此, 当一个微服务调用多次出现问题时(默认是10秒内20次当然 这个也能配置),hystrix就会采取熔断机制,不再继续调用你的方法(会在默认5秒钟内和电器短路一样,5秒钟后会试探性的先关闭熔断机制,但是如果这时候再失败一次{之前是20次} 那么又会重新进行熔断) 而是直接调用降级方法,这样就一定程度上避免了服务雪崩的问题。
限流
限流, 顾名思义, 就是限制你某个微服务的使用量(可用线程)
hystrix通过线程池的方式来管理你的微服务调用,他默认是一个线程池(10大小) 管理你的所有微服务,你可以 给某个微服务开辟新的线程池:
1)直接使用 @HystrixCommand 配置。
/**
* 获取订单信息
* @param name
* @return
*/
@GetMapping("/getOrder.do")
@HystrixCommand(fallbackMethod = "fallbackMethod",threadPoolKey = "order",
threadPoolProperties = {
@HystrixProperty(name = "coreSize",value = "2"),
@HystrixProperty(name = "maximumSize",value = "2"),
@HystrixProperty(name = "maxQueueSize",value = "1")
})
public R getOrder(@RequestParam String name){
//调用订单系统
Object object = restTemplate.getForObject(ORDER_URL+"/getOrder.do?name="+name,Object.class);
return R.success("操作成功",object);
}
public R fallbackMethod(String name){
System.out.println(name);
return R.error("调用order服务出现问题,降级信息");
}
比如, 这里coreSize给他值为2 那么假设你这个方法调用时间是3s执行完, 那么在3s内如果有超过2个请求进来的话,一个进入队列中等待, 剩下的请求则全部降级。
2) 在配置文件中配置
hystrix:
threadpool:
order-server: #你的GROUPKEY
coreSize: 2 #核心线程数
maximumSize: 2 #最大线程数
maxQueueSize: 1 #等待队列最大总容量,默认-1为无等待队列而不是无限容量
allowMaximumSizeToDivergeFromCoreSize: true #是否允许动态调整,必须为true才能让maximumSize生效
keepAliveTimeMinutes: 1 #非核心线程空闲多久后释放,单位 分钟
#queueSizeRejectionThreshold: 5 #等待队列运行时的最大容量,maxQueueSize不为-1才生效
在代码中直接使用。
/**
* 获取订单信息
* @param name
* @return
*/
@GetMapping("/getOrderServer.do")
@HystrixCommand(fallbackMethod = "fallbackMethod",threadPoolKey = "order-server")
public R getOrderServer(@RequestParam String name){
//调用订单系统
Object object = restTemplate.getForObject(ORDER_URL+"/getOrder.do?name="+name,Object.class);
return R.success("操作成功",object);
}
- threadPoolKey 就是在线程池唯一标识, hystrix 会拿你这个标识去计数,看线程占用是否超过了, 超过了就会直 接降级该次调用。
- coreSize 核心线程数量
- maximumSize 最大线程数量
- maxQueueSize 等待队列的数量
以上参数内有坑:
- 默认hystrix线程池为懒加载,第一次触发HystrixCommand才生成对应线程池
- 之所以要分maxQueueSize和queueSizeRejectionThreshold这两个参数,而不是直接适用maxQueueSize,是因为队列一旦创建就不可以改变大小,无法实现动态调整,所以才有了第二个参数
- 默认Hystrix执行线程池ThreadPoolExecutor比较懒,在队列没有达到容量上限时只会保持coreSize数量的线程,除非队列满了或者不启用队列,而不像Tomcat一样尽可能的创建线程,经测试如果启用了队列,queueSizeRejectionThreshold必须等于maxQueueSize才能让maximumSize生效,如果小于maxQueueSize,maximumSize永远不会生效,个人认为既然启用了断路器,尽量做熔断降级,不需要给很大的等待队列
- 虽然Hystrix使用新的线程执行任务,但是由于Servlet容器运行模型的限制,外部请求进入本地服务器以后,还是必须占用并阻塞一个Servlet线程(虽然Tomcat号称支持http-nio非阻塞,但实际上只是伪nio,只能针对HTTP-head部分读取做nio,真正的业务逻辑执行时仍然是阻塞模式),这是springboot的DispatcherServlet运行机制无法绕过的,所以开启Hystrix后,其全局总线程容量受到Servlet线程数限制(默认200个),且如果启用了Hystrix的queue,且线程数+queue数一旦超过了tomcat最大线程数,则Hystrix失效,其他请求仍然得不到执行
2.3、feign整合hystrix
feign 默认是支持hystrix的, 但是在Spring - cloud Dalston 版本之后就默认关闭了, 因为不一定业务需求要用的到,所以现在要使用首先得打开他,在yml文件加上如下配置:
feign:
hystrix:
enabled: true
加上配置之后降级方法怎么写呢?
// 使用 @FeignClient 注解来指定提供者的名字
@FeignClient(value = "server-order",fallback = OrderFeignClientFallBack.class )
public interface OrderFeignClient {
// 这里一定要注意需要使用的是提供者那端的请求相对路径,这里就相当于映射了
@RequestMapping(value = "/getOrder.do", method = RequestMethod.GET)
public Map getOrder(@RequestParam(value = "name") String name);
}
在feign客户端的注解上 有个属性叫fallback 然后指向一个类 OrderFeignClientFallBack 类:
@Component //一定要加!!!!!!!!!!!
public class OrderFeignClientFallBack implements OrderFeignClient {
@Override
public Map getOrder(String name) {
System.out.println(name+":进入降级方法");
Map result = new HashMap(4);
result.put("orderError","调用失败降级");
return result;
}
}
这样子,方法降级就写好了
当然可能你有这种需求, 需要拿到具体的错误信息, 那么可以这样写:
public class OrderServiceClientFallBackFactory implements FallbackFactory<OrderFeignClient> {
@Override
public OrderFeignClient create(Throwable cause) {
return new OrderFeignClient(){
@Override
public Map getOrder(String name) {
String message = cause.getMessage();
Map result = new HashMap(4);
result.put("orderError",message);
return result;
}
};
}
}
客户端指定一个fallbackFactory就好了
这个message 就是拿到的错误信息 至此, 就完成了feign与hystrix的整合。
三、配置信息相关
3.1、熔断相关
(1)熔断参数circuitBreaker.enabled的作用是什么?
答:circuitBreaker.enabled的作用是判断是否开启熔断,默认为true,
(2)熔断参数circuitBreaker.requestVolumeThreshold的作用是什么?
答:circuitBreaker.requestVolumeThreshld的作用是
统计一个窗口10s内熔断触发的最小个数,默认值20,
10s内请求数大于20个就启动熔断器,当请求符合熔断条件时将触发getFallback()。
(3)熔断参数circuitBreaker.sleepWindowInMiliseconds的作用是什么?
答:circuitBreaker.sleepWindowInMiliseconds的作用是熔断多少秒后去尝试请求,默认为500ms。
(4)熔断参数circuitBreaker.errorThresholdPercentage的作用是什么?
答:circuitBreaker.errorThresholdPercenntage的作用是判断当失败率达到多少百分比后熔断,默认配置下采样周期为10s,失败率为50%,请求错误率大于50%时就熔断,然后for循环发起请求,当请求符合熔断时将触发getFallback().
(5)熔断参数circuitBreaker.forceOpen的作用是什么?
答:circuitBreaker.forceOpen的作用是判断是否强制开启熔断,默认为false,置为true时,所有请求都将被拒绝,直接到fallback。
(6)熔断参数circuitBreaker.forceClosed的作用是什么?
答:circuitBreaker.forceColsed的作用是判断是否强制关闭熔断,默认为false,置为true时,将忽略错误。
3.2、线程池隔离
什么是线程池隔离?
答:线程池隔离是指每个服务接口使用一个线程池,以防止其中一个服务接口出现问题影响其他服务。
线程池隔离的优点是什么?
答:线程池隔离的优点:
使用线程池隔离可以完全隔离依赖的服务,请求线程可以快速回放
当线程池出现问题时,线程池隔离是独立的,不会影响其他服务和接口
当失败的服务再次变得可用时,线程池将清理并可立即恢复,而不需要一个长时间的恢复
独立的线程池提高了并发性
线程池隔离的缺点是什么?
答:线程池隔离的主要缺点是它们增加计算开销,每个命令的执行涉及到排队,调度和上下文切换都是在一个单独的线程上运行的。
相关参数:
(1)@HystrixCommand注解中的threadPoolProperties属性的作用是什么?
答:threadPoolProperties属性的作用是配置线程池基本信息
(2)@HystrixProperty注解的作用是什么?
答:@HystrixProperty注解的作用是配置Hystrix属性信息
(3)线程池隔离参数groupKey的作用是什么?
答:groupKey的作用是设置服务名,相同服务用一个名称,默认值为getClass().getSimpleName();在consumer里面为每个provider服务,设置group标识,一个group使用一个线程池
(4)线程池隔离参数commandKey的作用是什么?
答:commandKey的作用是配置接口名称,默认值为当前执行的方法名称
(5)线程池隔离参数threadPoolkey的作用是什么?
答:threadPoolKey的作用是配置线程池名称,配置全局唯一标识接口线程池的名称,相同线程池名称的线程池是同一个。默认值是分组名groupKey
(6)线程池隔离参数coreSize的作用是什么?
答:coreSize的作用是配置线程池的最大并发执行数,默认值为10
(7)线程池隔离参数maxQueueSize的作用是什么?
答:maxQueueSize的作用是设置BlockingQueue的最大长度,默认值为-1,如果使用正数,队列将从同步队列改为阻塞队列
(8)线程池隔离参数queueSizeRejectionThreshold的作用是什么?
答:queueSizeRejectionThreshold的作用是设置拒绝请求的临界值,默认值为5
(9)线程池隔离参数keepAliveTimeMinutes的作用是什么?
答:keepAliveTimeMinutes的作用是设置存活时间,默认值为1分钟,控制一个线程从实用完成
3.3、信号量隔离
(1)什么是信号量隔离?
答:信号量隔离是指在规定时间内只允许指定数量的信号量进行服务访问,其他得不到信号量的线程进入fallback。
(2)信号量隔离参数execution.isolation.strategy的作用是什么?
答:execution.isolation.strategy的作用是配置隔离策略,隔离策略有两种,分别为THREAD和SEMAPHORE,默认值为THREAD
(3)信号量隔离参数execution.isolation.thread.timeoutInMiliseconds的作用是什么?
答:execution.isolation.thread.timeoutInMilisecons的作用是设置超时时间,默认值为1000ms,在THREAD模式下,达到超时时间自动终端,在SEMAPHORE模式下,会等待执行完成后,再去判断是否超时
(4)信号量隔离参数execution.isolation.thread.interruptOnTimeout的作用是什么?
答:execution.isolation.thread.interruptOnTimeout的作用是判断是否打开超时线程中端,默认为true,在THREAD模式有效。
(5)信号量隔离参数execution.isolation.semaphore.maxConcurrentRequests的作用是什么?
答:execution.isolation.semaphore.maxConcurrentReqests的作用是设置信号量最大并发数,默认值10,SEMAPHORE模式下有效
(6)信号量隔离参数fallback.isolation.semaphore.maxConcurrentRequests的作用是什么?
答:fallback.isolation.semaphore.maxConcurrentRequest的作用是设置fallback最大并发数,默认值10,SEMAPHORE模式下有效。
3.4、线程池隔离和信号量隔离的区别
(1)线程池隔离和信号量隔离的区别
(2)什么情况下使用线程池隔离?
答:当请求并发量大,并且耗时长(请求耗时长一般是计算量大,或读数据库),采用线程池隔离,这样的话,可以保证大量的容器线程可用,不会由于服务原因,一直处于阻塞状态或等待状态,快速失败返回。
(3)什么情况下使用信号量隔离?
答:当请求并发量答,并且耗时短(请求耗时短可能是计算量小,或读缓存),采用信号量隔离,因为这类服务的返回通常会非常快,不会占用容器线程太长时间,而且也减少了线程切换的一些开销,提高了缓存服务的效率。
四、总结
Spring Cloud Hystrix实现了断路器、线程隔离等一系列服务保护功能。
-
Fallback(失败快速返回):当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝), 向调用方返回一个错误响应, 而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。
-
资源/依赖隔离(线程池隔离):它会为每一个依赖服务创建一个独立的线程池,这样就算某个依赖服务出现延迟过高的情况,也只是对该依赖服务的调用产生影响, 而不会拖慢其他的依赖服务。
Hystrix提供几个熔断关键参数:滑动窗口大小(20)、 熔断器开关间隔(5s)、错误率(50%)
-
每当20个请求中,有50%失败时,熔断器就会打开,此时再调用此服务,将会直接返回失败,不再调远程服务。
-
直到5s钟之后,重新检测该触发条件,判断是否把熔断器关闭,或者继续打开。
Hystrix还有请求合并、请求缓存这样强大的功能,在此我就不具体说明了,有兴趣的同学可继续深入学习~
附录一: 配置参数
Execution相关的属性的配置
hystrix.command.default.execution.isolation.strategy 隔离策略,默认是Thread, 可选Thread| Semaphor
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 命令执行超时时 间, 默认1000ms
hystrix.command.default.execution.timeout.enabled 执行是否启用超时,默认启用true
hystrix.command.default.execution.isolation.thread.interruptOnTimeout 发生超时是是否中断, 默认true
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests 最大并发请求 数,默认10,该参数当使用ExecutionIsolationStrategy.SEMAPHORE策略时才有效。如果达到最大并发请求 数, 请求会被拒绝。理论上选择semaphore size的原则和选择thread size一致,但选用semaphore时每次执行 的单元 要比较小且执行速度快(ms级别),否则的话应该用thread。 semaphore应该占整个容器(tomcat)的线程池的一小 部分。 Fallback相关的属性 这些参数可以应用于Hystrix的THREAD和SEMAPHORE策略
hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests 如果并发数达到 该设置值,请求会被拒绝和抛出异常并且fallback不会被调用。默认10
hystrix.command.default.fallback.enabled 当执行失败或者请求被拒绝,是否会尝试调用 hystrixCommand.getFallback() 。默认true Circuit Breaker相关的属性
hystrix.command.default.circuitBreaker.enabled 用来跟踪circuit的健康性,如果未达标则让request 短路。默认true
hystrix.command.default.circuitBreaker.requestVolumeThreshold 一个rolling window内最小的请 求数。如果设为20,那么当一个rolling window的时间内(比如说1个rolling window是10秒)收到19个请求, 即使19个请求都失败,也不会触发circuit break。默认20
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds 触发短路的时间值,当该值设 为5000时,则当触发circuit break后的5000毫秒内都会拒绝request,也就是5000毫秒后才会关闭circuit。 默 认5000
hystrix.command.default.circuitBreaker.errorThresholdPercentage错误比率阀值,如果错误率>=该 值,circuit会被打开,并短路所有请求触发fallback。默认50
hystrix.command.default.circuitBreaker.forceOpen 强制打开熔断器,如果打开这个开关,那么拒绝所 有 request,默认false
hystrix.command.default.circuitBreaker.forceClosed 强制关闭熔断器 如果这个开关打开,circuit将 一直关闭且忽略circuitBreaker.errorThresholdPercentage
Metrics相关参数
hystrix.command.default.metrics.rollingStats.timeInMilliseconds 设置统计的时间窗口值的,毫秒 值,circuit break 的打开会根据1个rolling window的统计来计算。若rolling window被设为10000毫秒, 则 rolling window会被分成n个buckets,每个bucket包含success,failure,timeout,rejection的次数 的统 计信息。默认10000
hystrix.command.default.metrics.rollingStats.numBuckets 设置一个rolling window被划分的数 量,若numBuckets=10,rolling window=10000,那么一个bucket的时间即1秒。必须符合rolling window % numberBuckets == 0。默认10
hystrix.command.default.metrics.rollingPercentile.enabled 执行时是否enable指标的计算和跟踪, 默认true
hystrix.command.default.metrics.rollingPercentile.timeInMilliseconds 设置rolling percentile window的时间,默认60000
hystrix.command.default.metrics.rollingPercentile.numBuckets 设置rolling percentile window的numberBuckets。逻辑同上。默认6
hystrix.command.default.metrics.rollingPercentile.bucketSize 如果bucket size=100,window =10s,若这10s里有500次执行,只有最后100次执行会被统计到bucket里去。增加该值会增加内存开销以及排序 的开 销。默认100
hystrix.command.default.metrics.healthSnapshot.intervalInMilliseconds 记录health 快照(用 来统计成功和错误绿)的间隔,默认500ms
Request Context 相关参数
hystrix.command.default.requestCache.enabled 默认true,需要重载getCacheKey(),返回null时不缓存
hystrix.command.default.requestLog.enabled 记录日志到HystrixRequestLog,默认true
Collapser Properties 相关参数
hystrix.collapser.default.maxRequestsInBatch 单次批处理的最大请求数,达到该数量触发批处理,默认 Integer.MAX_VALU
hystrix.collapser.default.timerDelayInMilliseconds 触发批处理的延迟,也可以为创建批处理的时间 +该值,默认10
hystrix.collapser.default.requestCache.enabled 是否对HystrixCollapser.execute() and HystrixCollapser.queue()的cache,默认true
ThreadPool 相关参数
线程数默认值10适用于大部分情况(有时可以设置得更小),如果需要设置得更大,那有个基本得公式可以 follow: requests per second at peak when healthy × 99th percentile latency in seconds + some breathing room 每秒最大支撑的请求数 (99%平均响应时间 + 缓存值) 比如:每秒能处理1000个请求,99%的请求 响应时间是60ms,那么公式是: 1000 (0.060+0.012)
基本得原则时保持线程池尽可能小,他主要是为了释放压力,防止资源被阻塞。 当一切都是正常的时候,线程池一般仅 会有1到2个线程激活来提供服务
hystrix.threadpool.default.coreSize 并发执行的最大线程数,默认10
hystrix.threadpool.default.maxQueueSize BlockingQueue的最大队列数,当设为-1,会使用 SynchronousQueue,值为正时使用LinkedBlcokingQueue。该设置只会在初始化时有效,之后不能修改 threadpool的queue size,除非reinitialising thread executor。默认-1。
hystrix.threadpool.default.queueSizeRejectionThreshold 即使maxQueueSize没有达到,达到 queueSizeRejectionThreshold该值后,请求也会被拒绝。因为maxQueueSize不能被动态修改,这个参数将允 许 我们动态设置该值。if maxQueueSize == 1,该字段将不起作用
hystrix.threadpool.default.keepAliveTimeMinutes 如果corePoolSize和maxPoolSize设成一样(默认 实现)该设置无效。如果通过plugin(https://github.com/Netflix/Hystrix/wiki/Plugins)使用自定义 实 现,该设置才有用,默认1.
hystrix.threadpool.default.metrics.rollingStats.timeInMilliseconds 线程池统计指标的时间,默 认10000
hystrix.threadpool.default.metrics.rollingStats.numBuckets 将rolling window划分为n个 buckets,默认10