原理探究
1、Hystrix 的设计宗旨
- 为第三方系统访问(通常是指通过网络) 中发送的延时和错误(例如:服务数据库异常)提供保护和控制.
- 终止复杂分布式系统中的级联故障 .
- 快速失败(熔断)和快速恢复.
- 回退(fallback) 并且在可能的情况下进行服务降级.
- 启用近乎实时的监视,警报和操作控制.
2、Hystrix 的设计原则(工作原理)
- 防止单个依赖服务耗尽整个容器(例如:tomcat,jboss等)用户线程
- 减少负载并快速失败,而不是排队(之间断路,而不是等待恢复)。
- 在允许的情况下提供备用机制,保护用户免受故障影响。
- 使用隔离技术 (例如隔离, 泳道, 断路) 去限制一个依赖服务故障带来的影响
- 通过近实时指标,监视和警报优化发现时间
- 通过在Hystrix的大多数方面中以低延迟传播配置更改来优化恢复时间,并支持动态属性更改,这使您可以通过低延迟反馈环路进行实时操作修改。
- 防止整个服务集群执行失败,而不仅仅是网络请求的失败(网络阻塞)。
3、Hystrix 如何实现设计原则
- 将依赖服务(或者是依赖项)包装在一个单独线程执行的 HystrixCommand 或 HystrixObservableCommand 对象中执行(命令模式)。
- 请求超时花费的时间超过定义的阈值(配置的超时时间)。Hystrix提供一个超时配置,这个配置比实际的请求时间要略高一些,这些请求若发生超时,会直接拒绝请求(这里也是返回超时异常的主要原因)。
- Hystrix 会维护一个小的线程池(或者信号量);如果信号量或者线程池已满,请求会直接被拒绝而不是等待或排队。
- 计算成功或失败 (通过Hystrix客户端抛出的异常), 超时, 和线程拒绝.
- 如果某个服务的发生错误的百分比超过阈值,则会触发断路器断路(跳闸)。在接线来的一段时间里会自动或者手动的停止特定请求(被执行断路的请求)。
- 对发生请求失败,请求拒绝,请求超时,或断路的请求执行 回退(Fallback)策略。
- 实时的监控和动态配置。
4、Hystrix流程图

5、Hystrix整个工作流如下
- 构造一个 HystrixCommand或HystrixObservableCommand对象,用于封装请求,并在构造方法配置请求被执行需要的参数;
- 执行命令,Hystrix提供了4种执行命令的方法,后面详述;
- 判断是否使用缓存响应请求,若启用了缓存,且缓存可用,直接使用缓存响应请求。Hystrix支持请求缓存,但需要用户自定义启动;
- 判断熔断器是否打开,如果打开,跳到第8步;
- 判断线程池/队列/信号量是否已满,已满则跳到第8步;
- 执行HystrixObservableCommand.construct()或HystrixCommand.run(),如果执行失败或者超时,跳到第8步;否则,跳到第9步;
- 统计熔断器监控指标;
- 走Fallback备用逻辑
- 返回请求响应
6、执行命令的几种方法
Hystrix提供了4种执行命令的方法,execute()和queue() 适用于HystrixCommand对象,而
observe()和toObservable()适用于HystrixObservableCommand对象。
1、execute()
以同步堵塞方式执行run(),只支持接收一个值对象。hystrix会从线程池中取一个线程来
执行run(),并等待返回值。
2、queue()
以异步非阻塞方式执行run(),只支持接收一个值对象。调用queue()就直接返回一个
Future对象。可通过Future.get()拿到run()的返回结果,但Future.get()是阻塞执行的。
若执行成功,Future.get()返回单个返回值。当执行失败时,如果没有重写fallback,
Future.get()抛出异常。
3、observe()
事件注册前执行run()/construct(),支持接收多个值对象,取决于发射源。调用observe()
会返回一个hotObservable,也就是说,调用observe()自动触发执行run()/construct(),
无论是否存在订阅者。
如果继承的是HystrixCommand,hystrix会从线程池中取一个线程以非阻塞方式执行
run();如果继承的是HystrixObservableCommand,将以调用线程阻塞执construct()。
observe()使用方法:
调用observe()会返回一个Observable对象
调用这个Observable对象的subscribe()方法完成事件注册,从而获取结果
4、toObservable()
事件注册后执行run()/construct(),支持接收多个值对象,取决于发射源。调用
toObservable()会返回一个cold Observable,也就是说,调用toObservable()不会立即
触发执行run()/construct(),必须有订阅者订阅Observable时才会执行。
如果继承的是HystrixCommand,hystrix会从线程池中取一个线程以非阻塞方式执行
run(),调用线程不必等待run();如果继承的是HystrixObservableCommand,将以调用
线程堵塞执行construct(),调用线程需等待construct()执行完才能继续往下走。
toObservable()使用方法:
调用observe()会返回一个Observable对象
调用这个Observable对象的subscribe()方法完成事件注册,从而获取结果
需注意的是,HystrixCommand也支持toObservable()和observe(),但是即使将
HystrixCommand转换成Observable,它也只能发射一个值对象。只有
HystrixObservableCommand才支持发射多个值对象。
7、几种执行方法之间的关系

execute()实际是调用了queue().get()
queue()实际调用了toObservable().toBlocking().toFuture()
observe()实际调用toObservable()获得一个cold Observable,再创建一个ReplaySubject对象订阅Observable,将源 Observable转化为hot Observable。因此调用observe()会自动触发执行run()/construct()。
Hystrix总是以Observable的形式作为响应返回,不同执行命令的方法只是进行了相应的转换。
熔断
1、简介
现实生活中,可能大家都有注意到家庭电路中通常会安装一个保险盒,当负载过载时,保险盒中的保险丝会自动熔断,以保护电路及家里的各种电器,这就是熔断器的一个常见例子。Hystrix中的熔断器(Circuit Breaker)也是起类似作用,Hystrix在运行过程中会向每个commandKey对应的熔断器报告成功、失败、超时和拒绝的状态,熔断器维护并统计这些数据,并根据这些统计信息来决策熔断开关是否打开。如果打开,熔断后续请求,快速返回。隔一段时间(默认是5s)之后熔断器尝试半开,放入一部分流量请求进来,相当于对依赖服务进行一次健康检查,如果请求成功,熔断器关闭。
2、简单配置
Circuit Breaker主要包括如下6个参数:
- circuitBreaker.enabled — 是否启用熔断器,默认是TRUE。
- circuitBreaker.forceOpen — 熔断器强制打开,始终保持打开状态,不关注熔断开关的实际状态。默认值FLASE。
- circuitBreaker.forceClosed — 熔断器强制关闭,始终保持关闭状态,不关注熔断开关的实际状态。默认值FLASE。
- circuitBreaker.errorThresholdPercentage — 错误率,默认值50%,例如一段时间(10s)内有100个请求,其中有54个超时或者异常,那么这段时间内的错误率是54%,大于了默认值50%,这种情况下会触发熔断器打开。
- circuitBreaker.requestVolumeThreshold — 默认值20。含义是一段时间内至少有20个请求才进行errorThresholdPercentage计算。比如一段时间了有19个请求,且这些请求全部失败了,错误率是100%,但熔断器不会打开,总请求数不满足20。
- circuitBreaker.sleepWindowInMilliseconds — 半开状态试探睡眠时间,默认值5000ms。如:当熔断器开启5000ms之后,会尝试放过去一部分流量进行试探,确定依赖服务是否恢复。
3、工作原理

第一步,调用allowRequest()判断是否允许将请求提交到线程池
如果熔断器强制打开,circuitBreaker.forceOpen为true,不允许放行,返回。
如果熔断器强制关闭,circuitBreaker.forceClosed为true,允许放行。此外不必关注熔断器实际状态,也就是说熔断器仍然会维护统计数据和开关状态,只是不生效而已。
第二步,调用isOpen()判断熔断器开关是否打开
如果熔断器开关打开,进入第三步,否则继续;
如果一个周期内总的请求数小于circuitBreaker.requestVolumeThreshold的值,允许请求放行,否则继续;
如果一个周期内错误率小于circuitBreaker.errorThresholdPercentage的值,允许请求放行。否则,打开熔断器开关,进入第三步。
第三步,调用allowSingleTest()判断是否允许单个请求通行,检查依赖服务是否恢复
如果熔断器打开,且距离熔断器打开的时间或上一次试探请求放行的时间超过circuitBreaker.sleepWindowInMilliseconds的值时,熔断器器进入半开状态,允许放行一个试探请求;否则,不允许放行。
此外,为了提供决策依据,每个熔断器默认维护了10个bucket,每秒一个bucket,当新的bucket被创建时,最旧的bucket会被抛弃。其中每个blucket维护了请求成功、失败、超时、拒绝的计数器,Hystrix负责收集并统计这些计数器。
4、熔断降级实现方法
@RestController@RequestMapping("/book")@DefaultProperties(defaultFallback = "selBookFail")//指定默认的失败回调方法public class BookController {@Autowiredprivate BookService bookService;@PostMapping("/add")public boolean addBook(@RequestBody Book book){return bookService.addBook(book);};@GetMapping("/get/{bookId}")@HystrixCommand(commandProperties ={@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")})//一旦调用服务方法失败并抛出了错误信息后会自动调用指定方法public Book selOneBook(@PathVariable("bookId") Integer bookId){System.out.println("BookProviderController:"+bookId);Book book = bookService.selOneBook(bookId);if (book == null){throw new RuntimeException("没有此ID信息");}return book;};//自定义失败备用方法public Book selBookFail(@PathVariable("bookId") Integer bookId){System.out.println("selFailMethod:"+bookId);return new Book().setBookId(bookId).setBookName("此ID:"+bookId+"没有对应的信息,请检查");}@GetMapping("/list")@HystrixCommand(commandProperties ={@HystrixProperty(name = "execution.isolation.strategy",value = "THREAD")},threadPoolProperties = {@HystrixProperty(name = "coreSize",value = "3"),@HystrixProperty(name = "maxQueueSize",value = "5"),@HystrixProperty(name = "queueSizeRejectionThreshold",value = "5")})public List<Book> selAllBook(){return bookService.selAllBook();};@DeleteMapping("/del/{id}")@HystrixCommandpublic boolean delBook(@PathVariable("id") Integer bookId){return bookService.delBook(bookId);};@Autowiredprivate DiscoveryClient client;@GetMapping("/discovery")public Object getDiscovery(){//获取服务列表清单List<String> clientServices = client.getServices();System.out.println(clientServices);//获取具体的一个微服务List<ServiceInstance> instances = client.getInstances("SPRINGCLOUD-PROVIDER-BOOK-8001");for (ServiceInstance instance : instances) {System.out.println(instance.getServiceId()+instance.getPort()+instance.getUri()+instance.getHost());}return this.client;}}
② 客户端实现
③ 网关实现
5、隔离模式
Hystrix提供了两种隔离模式:线程池隔离模式、信号量隔离模式。
线程池隔离模式:使用一个线程池来存储当前请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求先入线程池队列。这种方式要为每个依赖服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)
信号量隔离模式:使用一个原子计数器(或信号量)记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃该类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)
6、主次模式
有时系统具有两种行为- 主要和次要,或主要和故障转移。主要和次要逻辑涉及到不同的网络调用和业务逻辑,所以需要将主次逻辑封装在不同的Command中,使用线程池进行隔离。为了实现主从逻辑切换,可以将主次command封装在外观HystrixCommand的run方法中,并结合配置中心设置的开关切换主从逻辑。由于主次逻辑都是经过线程池隔离的HystrixCommand,因此外观HystrixCommand可以使用信号量隔离,而没有必要使用线程池隔离引入不必要的开销。原理图如下:

主次模型的使用场景还是很多的。如当系统升级新功能时,如果新版本的功能出现问题,通过开关控制降级调用旧版本的功能。示例代码如下:public class CommandFacadeWithPrimarySecondary extends HystrixCommand<String> {private final static DynamicBooleanProperty usePrimary = DynamicPropertyFactory.getInstance().getBooleanProperty("primarySecondary.usePrimary", true);private final int id;public CommandFacadeWithPrimarySecondary(int id) {super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("SystemX")).andCommandKey(HystrixCommandKey.Factory.asKey("PrimarySecondaryCommand")).andCommandPropertiesDefaults(// 由于主次command已经使用线程池隔离,Facade Command使用信号量隔离即可HystrixCommandProperties.Setter().withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE)));this.id = id;}@Overrideprotected String run() {if (usePrimary.get()) {return new PrimaryCommand(id).execute();} else {return new SecondaryCommand(id).execute();}}@Overrideprotected String getFallback() {return "static-fallback-" + id;}@Overrideprotected String getCacheKey() {return String.valueOf(id);}private static class PrimaryCommand extends HystrixCommand<String> {private final int id;private PrimaryCommand(int id) {super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("SystemX")).andCommandKey(HystrixCommandKey.Factory.asKey("PrimaryCommand")).andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("PrimaryCommand")).andCommandPropertiesDefaults( HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(600)));this.id = id;}@Overrideprotected String run() {return "responseFromPrimary-" + id;}}private static class SecondaryCommand extends HystrixCommand<String> {private final int id;private SecondaryCommand(int id) {super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("SystemX")).andCommandKey(HystrixCommandKey.Factory.asKey("SecondaryCommand")).andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("SecondaryCommand")).andCommandPropertiesDefaults( HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(100)));this.id = id;}@Overrideprotected String run() {return "responseFromSecondary-" + id;}}public static class UnitTest {@Testpublic void testPrimary() {HystrixRequestContext context = HystrixRequestContext.initializeContext();try {ConfigurationManager.getConfigInstance().setProperty("primarySecondary.usePrimary", true);assertEquals("responseFromPrimary-20", new CommandFacadeWithPrimarySecondary(20).execute());} finally {context.shutdown();ConfigurationManager.getConfigInstance().clear();}}@Testpublic void testSecondary() {HystrixRequestContext context = HystrixRequestContext.initializeContext();try {ConfigurationManager.getConfigInstance().setProperty("primarySecondary.usePrimary", false);assertEquals("responseFromSecondary-20", new CommandFacadeWithPrimarySecondary(20).execute());} finally {context.shutdown();ConfigurationManager.getConfigInstance().clear();}}}}
通常情况下,建议重写getFallBack或resumeWithFallback提供自己的备用逻辑,
但不建议在回退逻辑中执行任何可能失败的操作7、@HystrixCommand注解属性
@HystrixCommand(fallbackMethod = "xxx_method", // 指定降级方法groupKey = "strGroupCommand", // 分组的keycommandKey = "strCommarld", // 命令分组的keythreadPoolKey = "strThreadPool", // 线程池key值,相同key共用一个线程池;这三个key都是划分线程池相关commandProperties = {//设置隔离策略,THREAD 表示线程她SEMAPHORE:信号他隔离@HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),//当隔离策略选择信号他隔离的时候,用来设置信号地的大小(最大并发数)@HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "10"),//配置命令执行的超时时间@HystrixProperty(name = "execution.isolation.thread.timeoutinMilliseconds", value = "10"),//是否启用超时时间@HystrixProperty(name = "execution.timeout.enabled", value = "true"),//执行超时的时候是否中断@HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout", value = "true"),//执行被取消的时候是否中断@HystrixProperty(name = "execution.isolation.thread.interruptOnCancel", value = "true"),//允许回调方法执行的最大并发数@HystrixProperty(name = "fallback.isolation.semaphore.maxConcurrentRequests", value = "10"),//服务降级是否启用,是否执行回调函数@HystrixProperty(name = "fallback.enabled", value = "true"),@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),//该属性用来设置在滚动时间窗中,断路器熔断的最小请求数。例如,默认该值为20的时候,//如果滚动时间窗(默认10秒)内仅收到了19个请求,即使这19个请求都失败了, 断路器也不会打开。@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"),// 该属性用来设置在熔动时间窗中表示在滚动时间窗中,在请求数量超过// circuitBreaker.requestVolumeThreshold 的情况下,如果错误请求数的百分比超过50,//就把断路器设置为“打开”状态,否则就设置为“关闭”状态。@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),// 该属性用来设置当断路器打开之后的休眠时间窗。休眠时间窗结束之后,//会将断路器置为"半开”状态,尝试熔断的请求命令,如果低然失败就将断路器继续设置为"打开”状态,//如果成功就设置为"关闭”状态。@HystrixProperty(name = "circuitBreaker.sleepWindowinMilliseconds", value = "5009"),//断路器强制打开@HystrixProperty(name = "circuitBreaker.force0pen", value = "false"),// 断路器强制关闭@HystrixProperty(name = "circuitBreaker.forceClosed", value = "false"),//滚动时间窗设置,该时间用于断路器判断健康度时需要收集信息的持续时间@HystrixProperty(name = "metrics.rollingStats.timeinMilliseconds", value = "10000"),//该属性用来设置滚动时间窗统计指标信息时划分”桶"的数量,断路器在收集指标信息的时候会根据设置的时间窗长度拆分成多个"相"来累计各度量值,每个”桶"记录了-段时间内的采集指标。//比如10秒内拆分成10个”桶"收集这样,所以timeinMilliseconds 必须能被numBuckets 整除。否则会抛异常@HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "10"),//该属性用来设置对命令执行的延迟是否使用百分位数来跟踪和计算。如果设置为false,那么所有的概要统计都将返回-1.@HystrixProperty(name = "metrics .rollingPercentile.enabled", value = "false"),//该属性用来设置百分位统计的滚动窗口的持续时间, 单位为毫秒。@HystrixProperty(name = "metrics.rollingPercentile.timeInMilliseconds", value = "60000"),//该属性用来设置百分位统计演动窗口中使用“桶”的数量。@HystrixProperty(name = "metrics.rollingPercentile.numBuckets", value = "60000"),// 该属性用来设置在执行过程中每个 “桶”中保留的最大执行次数。如果在滚动时间窗内发生超过该设定值的执行次数,就从最初的位置开始重写。例如,将该值设置为100,燎动窗口为10秒, 若在10秒内一 一个“桶 ” 中发生7500次执行,//那么该“桶”中只保留最后的100次执行的统计。另外,增加该值的大小将会增加内存量的消耗, 并增加排序百分位数所需的计算@HystrixProperty(name = "metrics.rollingPercentile.bucketSize", value = "100"),//该属性用来设置采集影响断路器状态的健康快照(请求的成功、错误百分比) 的间隔等待时间。@HystrixProperty(name = "metrics.healthSnapshot.intervalinMilliseconds", value = "500"),//是否开启请求缓存@HystrixProperty(name = "requestCache.enabled", value = "true"),// HystrixCommand的执行和时间是否打印日志到HystrixRequestLog中@HystrixProperty(name = "requestLog.enabled", value = "true"),},threadPoolProperties = {//该参数用来设置执行命令线程他的核心线程数,该值 也就是命令执行的最大并发量@HystrixProperty(name = "coreSize", value = "10"),//该参数用来设置线程她的最大队列大小。当设置为-1时,线程池将使用SynchronousQueue 实现的队列,// 否则将使用LinkedBlocakingQueue实现队列@HystrixProperty(name = "maxQueueSize", value = "-1"),// 该参数用来为队列设置拒绝阀值。 通过该参数, 即使队列没有达到最大值也能拒绝请求。//該参数主要是対linkedBlockingQueue 队列的朴充,因为linkedBlockingQueue//队列不能动态修改它的对象大小,而通过该属性就可以调整拒绝请求的队列大小了。@HystrixProperty(name = "queueSizeRejectionThreshold", value = "5"),})
8、Hystrix参数配置
hystrix.command.default和hystrix.threadpool.default中的default为默认CommandKey
①、Execution相关的属性的配置:
- hystrix.command.default.execution.isolation.strategy 隔离策略,默认是Thread, 可选Thread|Semaphore
- 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_VALUE
- 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,那么公式是:(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
