资源隔离 :让你的系统里,某一块东西,在故障的情况下,不会耗尽系统所有的资源,比如线程资源。 限流 :高并发的流量涌入进来,比如说突然间一秒钟100万QPS,废掉了,10万QPS进入系统,其他90万QPS被拒绝了。 熔断 :系统后端的一些依赖,出了一些故障,比如说mysql挂掉了,每次请求都是报错的,熔断了,后续的请求过来直接不接收了,拒绝访问,10分钟之后再尝试去看看mysql恢复没有 降级 :mysql挂了,系统发现了,自动降级,从内存里存的少量数据中,去提取一些数据出来 运维监控 :监控+报警+优化,各种异常的情况,有问题就及时报警,优化一些系统的配置和参数,或者代码。

二、雪崩效应

分布式系统环境下,服务间类似依赖非常常见,一个业务调用通常依赖多个基础服务。
比如我们现在有3个业务调用分别是 查询订单 查询商品 查询用户 ,且这三个业务请求都是依赖第三方服务- 订单服务 商品服务 用户服务 。三个服务均是通过RPC调用。当查询 订单服务 ,假如线程阻塞了,这个时候后续有大量的 查询订单 请求过来,那么容器中的线程数量则会持续增加直致CPU资源耗尽到100%,整个服务对外不可用,并且这种可不用可能沿请求调用链向上传递,这种现象在集群环境下就是雪崩。如下图

image.png
复杂分布式体系结构中的应用程序有几十个依赖项,每个依赖项在某个时候都不可避免地会失败。如果主机应用程序没有从这些外部故障中隔离出来,那么它就有可能与这些外部故障一起宕机。

当一切正常时,请求流可以是这样的:

一个应用中,任意一个点的不可用或者响应延时都有可能造成服务不可用
更可怕的是,被hang住的请求会很快耗尽系统的资源,当该类请求越来越多,占用的计算机资源越来越多的时候,会导致系统瓶颈出现,造成其他的请求同样不可用,最终导致业务系统崩溃

雪崩效应常见场景

  • 硬件故障:如服务器宕机,机房断电,光纤被挖断等。
  • 流量激增:如异常流量,重试加大流量等。
  • 缓存穿透:一般发生在应用重启,所有缓存失效时,以及短时间内大量缓存失效时。大量的缓存不命中,使请求直击后端服务,造成服务提供者超负荷运行,引起服务不可用。
  • 程序BUG:如程序逻辑导致内存泄漏,JVM长时间FullGC等。
  • 同步等待:服务间采用同步调用模式,同步等待造成的资源耗尽。
  • 最终的结果就是一个服务不可用导致一系列服务的不可用,而往往这种后果往往无法预料的。

    雪崩效应应对策略

  • 硬件故障:多机房容灾、异地多活等。
  • 流量激增:服务自动扩容、流量控制(限流、关闭重试)等。
  • 缓存穿透:缓存预加载、缓存异步加载等。
  • 程序BUG:修改程序bug、及时释放资源等。
  • 同步等待:资源隔离、MQ解耦、不可用服务调用快速失败等。资源隔离通常指不同服务调用采用不同的线程池;不可用服务调用快速失败一般通过超时机制,熔断器以及熔断后降级方法等方案实现。
  • 三、Hystrix的产生

    1. Hystrix的设计目标

  • 对来自依赖的延迟和故障进行防护和控制——这些依赖通常都是通过网络访问的
  • 阻止故障的连锁反应
  • 快速失败并迅速恢复
  • 回退并优雅降级
  • 提供近实时的监控与告警
  • 2. Hystrix遵循的设计原则

  • 防止任何单独的依赖耗尽资源(线程)
  • 过载立即切断并快速失败,防止排队
  • 尽可能提供回退以保护用户免受故障
  • 使用隔离技术(例如隔板,泳道和断路器模式)来限制任何一个依赖的影响
  • 通过近实时的指标,监控和告警,确保故障被及时发现
  • 通过动态修改配置属性,确保故障及时恢复
  • 防止整个依赖客户端执行失败,而不仅仅是网络通信
  • 3. Hystrix如何实现这些设计目标?

  • 使用命令模式将所有对外部服务(或依赖关系)的调用包装在HystrixCommand或HystrixObservableCommand对象中,并将该对象放在单独的线程中执行;
  • 每个依赖都维护着一个线程池(或信号量),线程池被耗尽则拒绝请求(而不是让请求排队)。
  • 记录请求成功,失败,超时和线程拒绝。
    服务错误百分比超过了阈值,熔断器开关自动打开,一段时间内停止对该服务的所有请求。
    请求失败,被拒绝,超时或熔断时执行降级逻辑。
    近实时地监控指标和配置的修改。

    1:每次调用创建一个新的HystrixCommand,把依赖调用封装在run()方法中.
    2:执行execute()/queue做同步或异步调用.
    3:判断熔断器(circuit-breaker)是否打开,如果打开跳到步骤8,进行降级策略,如果关闭进入步骤.
    4:判断线程池/队列/信号量是否跑满,如果跑满进入降级步骤8,否则继续后续步骤.
    5:调用HystrixCommand的run方法.运行依赖逻辑
    5a:依赖逻辑调用超时,进入步骤8.
    6:判断逻辑是否调用成功
    6a:返回成功调用结果
    6b:调用出错,进入步骤8.
    7:计算熔断器状态,所有的运行状态(成功, 失败, 拒绝,超时)上报给熔断器,用于统计从而判断熔断器状态.
    8:getFallback()降级逻辑.
    以下四种情况将触发getFallback调用:
    (1):run()方法抛出非HystrixBadRequestException异常。
    (2):run()方法调用超时
    (3):熔断器开启拦截调用
    (4):线程池/队列/信号量是否跑满
    8a:没有实现getFallback的Command将直接抛出异常
    8b:fallback降级逻辑调用成功直接返回
    8c:降级逻辑调用失败抛出异常
    9:返回执行成功结果

    image.png
    (1) 线程池隔离模式 :使用一个线程池来存储当前的请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求堆积入线程池队列。这种方式需要为每个依赖的服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)
    (2) 信号量隔离模式 :使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃改类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)

    区别(两种隔离方式只能选其一):

    线程池隔离 信号量隔离

    线程池和信号量都支持熔断和限流。相比线程池,信号量不需要线程切换,因此避免了不必要的开销。但是信号量不支持异步,也不支持超时,也就是说当所请求的服务不可用时,信号量会控制超过限制的请求立即返回,但是已经持有信号量的线程只能等待服务响应或从超时中返回,即可能出现长时间等待。线程池模式下,当超过指定时间未响应的服务,Hystrix会通过响应中断的方式通知线程立即结束并返回。

    2. 融断

    正常状态下,电路处于关闭状态(Closed),如果调用持续出错或者超时,电路被打开进入熔断状态(Open),后续一段时间内的所有调用都会被拒绝(Fail Fast),一段时间以后,保护器会尝试进入半熔断状态(Half-Open),允许少量请求进来尝试,如果调用仍然失败,则回到熔断状态,如果调用成功,则回到电路闭合状态;

    3. 降级

    可能大家会混淆“融断”和“降级”两个概念。
    在股票市场,熔断这个词大家都不陌生,是指当股指波幅达到某个点后,交易所为控制风险采取的暂停交易措施。相应的,服务熔断一般是指软件系统中,由于某些原因使得服务出现了过载现象,为防止造成整个系统故障,从而采用的一种保护措施,所以很多地方把熔断亦称为过载保护。
    大家都见过女生旅行吧,大号的旅行箱是必备物,平常走走近处绰绰有余,但一旦出个远门,再大的箱子都白搭了,怎么办呢?常见的情景就是把物品拿出来分分堆,比了又比,最后一些非必需品的就忍痛放下了,等到下次箱子够用了,再带上用一用。而服务降级,就是这么回事,整体资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开启回来。
    二者的目标是一致的,目的都是保证上游服务的稳定性。但其关注的重点并不一样,融断对下层依赖的服务并不级(或者说孰轻孰重),一旦产生故障就断掉;而降级需要对下层依赖的业务分级,把产生故障的丢了,换一个轻量级的方案,是一种退而求其次的方法。
    根据业务场景的不同,一般采用以下两种模式:
    第一种(最常用) 如果服务失败,则我们通过fallback进行降级,返回静态值。
    <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>2.0.2.RELEASE</version> </dependency>

    2. 修改启动类

    在主函数上添加注解 @EnableCircuitBreaker ,启动 Hystrix
    Circuit n. 环行; 环行路线; 电路; 线路; 巡回赛;

    @SpringBootApplication
    @EnableEurekaClient//声明为eureka 客户端
    @EnableFeignClients //启动Feign
    @EnableCircuitBreaker //启动Hystrix
    public class FuturecloudHystrixApplication
        public static void main( String[] args )
            SpringApplication.run(FuturecloudHystrixApplication.class,args);
    

    3. Feign 接口

    (可以不使用)

    @FeignClient(name = "futurecloud-user")   //通过注解指定依赖服务
    public interface FeignClientInterfaces {
       @RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
       User getUserById(@PathVariable("id") Long id);
        @GetMapping("/getUser/{id}")
        User getUser(@PathVariable("id") Long id);
        @RequestMapping(value = "/find/user/{id}",method = RequestMethod.POST)
        User findUserById(@PathVariable("id") Long id);
    

    4、使用Hystix熔断器

    @RestController
    public class FuturecloudHystrixController {
        @Autowired
       private FeignClientInterfaces feignClientInterfaces;
        @RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
        public User getUserById(@PathVariable("id") Long id){
            User user = feignClientInterfaces.getUserById(id);
            return user;
        @GetMapping("/getUser/{id}")
        public User getUser(@PathVariable("id") Long id){
            User user = feignClientInterfaces.getUser(id);
            return user;
         * 使用Hystrix熔断器,当调用findUserById失败后,调用forbackFindUserById方法
         * @param id
         * @return
        @HystrixCommand(fallbackMethod = "forbackFindUserById")
        @RequestMapping(value = "/find/user/{id}",method = RequestMethod.GET)
        public User findUserById(@PathVariable("id") Long id){
            User user = feignClientInterfaces.findUserById(id);
            int a = 4/0;
            return user;
        public User forbackFindUserById(Long id){
            User user = new User();
            user.setId(-400L);
            user.setUsername("hystrix-fallback");
            user.setMail("hystrix-fallback@sina.com");
            user.setPhone("13838384381");
            user.setCreateDate(new Date());
            return  user;
    

    使用这个注解@HystrixCommand来定义Hystrix的熔断器,查看HystrixCommand源码,这个注解有10个属性,
    我们使用fallbackMethod属性,来指定接口调用失败后执行的方法。

    *********************************************************************************************************************************************************************** commandKey 配置全局唯一标识服务的名称,比如,库存系统有一个获取库存服务,那么就可以为这个服务起一个名字来唯一识别该服务,如果不配置,则默认是@HystrixCommand注解修饰的函数的函数名。 groupKey 一个比较重要的注解,配置全局唯一标识服务分组的名称,比如,库存系统就是一个服务分组。通过设置分组,Hystrix会根据组来组织和统计命令的告、仪表盘等信息。Hystrix命令默认的线程划分也是根据命令组来实现。默认情况下,Hystrix会让相同组名的命令使用同一个线程池,所以我们需要在创建Hystrix命令时为其指定命令组来实现默认的线程池划分。此外,Hystrix还提供了通过设置threadPoolKey来对线程池进行设置。建议最好设置该参数,使用threadPoolKey来控制线程池组。 threadPoolKey 对线程池进行设定,细粒度的配置,相当于对单个服务的线程池信息进行设置,也可多个服务设置同一个threadPoolKey构成线程组。 fallbackMethod @HystrixCommand注解修饰的函数的回调函数,@HystrixCommand修饰的函数必须和这个回调函数定义在同一个类中,因为定义在了同一个类中,所以fackback method可以是public/private均可。 commandProperties 配置该命令的一些参数,如executionIsolationStrategy配置执行隔离策略,默认是使用线程隔离,此处我们配置为THREAD,即线程池隔离。参见:com.netflix.hystrix.HystrixCommandProperties中各个参数的定义。 threadPoolProperties 线程池相关参数设置,具体可以设置哪些参数请见:com.netflix.hystrix.HystrixThreadPoolProperties ignoreExceptions 调用服务时,除了HystrixBadRequestException之外,其他@HystrixCommand修饰的函数抛出的异常均会被Hystrix认为命令执行失败而触发服务降级的处理逻辑(调用fallbackMethod指定的回调函数),所以当需要在命令执行中抛出不触发降级的异常时来使用它,通过这个参数指定,哪些异常抛出时不触发降级(不去调用fallbackMethod),而是将异常向上抛出。 observableExecutionMode 定义hystrix observable command的模式; raiseHystrixExceptions 任何不可忽略的异常都包含在HystrixRuntimeException中; defaultFallback 默认的回调函数,该函数的函数体不能有入参,返回值类型与@HystrixCommand修饰的函数体的返回值一致。如果指定了fallbackMethod,则fallbackMethod优先级更高。

    5. application.yml

    server:
      port: 8906
    spring:
      application:
        name: futurecloud-hystrix
    #将此服务注册到eureka 服务上
    eureka:
      client:
        serviceUrl:
          defaultZone: http://user:123@localhost:10000/eureka
      instance:
        prefer-ip-address: true  #将注册到eureka服务的实例使用ip地址
    #Feign日志的配置
    logging:
      level:
        com.futurecloud.feign.interfaces.CustomFeignClient: DEBUG
    

    启动eureka 服务futurecloud-service,
    启动服务提供者服务futurecloud-user,
    启动此服务futurecloud-hystrix
    访问http://localhost:8906/order/20 ,进入到了@HystrixCommand指定的方法forbackFindUserById

    五、Feign 使用Hystrix

    在Feign 接口中定义了依赖服务的接口,当Feign调用依赖服务的接口失败时怎么办?
    我们也可以在Feign中利用Hystrix的功能,当Feign 调用依赖服务的接口失败时,通过Hystrix调用指定的方法,Spring Cloud默认为Feign整合了Hystrix,但在Spring Cloud 基于Spring boot 2.x的版本中,默认是Feign是关闭Hystrix的。
    那么Feign与Hystrix怎么配合使用呢?

    1、创建项目futurecloud-feign-hystrix

    注意:不需要添加依赖spring-cloud-starter-netflix-hystrix,Spring Cloud默认已为Feign整合了Hystrix。spring boot 主函数也不需要添加注解@EnableCircuitBreaker 来开启Hystrix。主函数类如下:

    @SpringBootApplication
    @EnableEurekaClient //声明为eureka 客户端
    @EnableFeignClients //启动Feign
    public class FuturecloudFeignHystrixApplication
        public static void main( String[] args )
            SpringApplication.run(FuturecloudFeignHystrixApplication.class,args);
    

    2. 开启Hystrix在application.yml中配置

    #开启hystrix配置
    feign:
      hystrix:
        enabled: true
    

    2、Feign 使用fallback 方式进行Hystrix的回退

    在定义Feign接口时,我们可以指定Feign接口中的方法调用失败后的一个回调类,这个类实现此Feign接口,
    Feign接口代码如下:

    @FeignClient(name = "futurecloud-user",fallback = FeignHystrixFallback.class)   //指定依赖服务Hystrixd的回调类
    public interface FeignInterface {
        @GetMapping("/user/{id}")
        User getUser(@PathVariable("id") Long id);
        @GetMapping("/getObject")
        User getObject(User user);
        @GetMapping("/find//user/{id}")
        User findUser(@PathVariable("id") Long id);
    

    FeignHystrixFallback 代码如下:

    @Component
    public class FeignHystrixFallback implements FeignInterface{
        @Override
        public User getUser(Long id) {
            User user = new User();
            user.setId(-401L);
            user.setUsername("01-feignHystrixFallback");
            user.setMail("hystrix-fallback@sina.com");
            user.setPhone("13838389438");
            user.setCreateDate(new Date());
            return  user;
        @Override
        public User getObject(User user) {
            user = new User();
            user.setId(-402L);
            user.setUsername("02-feignHystrixFallback");
            user.setMail("hystrix-fallback@sina.com");
            user.setPhone("13838389438");
            user.setCreateDate(new Date());
            return  user;
        @Override
        public User findUser(Long id) {
            User user = new User();
            user.setId(-403L);
            user.setUsername("03-feignHystrixFallback");
            user.setMail("hystrix-fallback@sina.com");
            user.setPhone("13838389438");
            user.setCreateDate(new Date());
            return  user;
    

    注意:要添加注解@Component,否则Spring boot 找不到这个bean

    启动eureka 服务futurecloud-service,
    启动服务提供者服务futurecloud-user,
    启动此服务futurecloud-feign-hystrix
    访问http://localhost:8907/order/20 ,成功访问
    将服务futurecloud-user关掉,再一次访问http://localhost:8907/order/20,调用了fallback指定的FeignHystrixFallback中的方法。

    3. Feign 使用fallbackFactory方式进行Hystrix的回退

    在Feign接口中指定使用fallbackFactory工厂类,其实就是实现Feign接口的匿名类
    Feign接口定义如下:

    @FeignClient(name = "futurecloud-user",fallbackFactory = FeignHystrixFallbackFactory.class)
    public interface FeignInterface {
        @GetMapping("/user/{id}")
        User getUser(@PathVariable("id") Long id);
        @GetMapping("/getObject")
        User getObject(User user);
        @GetMapping("/find//user/{id}")
        User findUser(@PathVariable("id") Long id);
    

    FeignHystrixFallbackFactory代码如下:

    @Component
    public class FeignHystrixFallbackFactory implements FallbackFactory<FeignInterface>{
        @Override
        public FeignInterface create(Throwable throwable) {
            return new FeignInterface() {
                @Override
                public User getUser(Long id) {
                    User user = new User();
                    user.setId(-404L);
                    user.setUsername("01-feignHystrixFallbackFactory");
                    user.setMail("hystrix-fallback@sina.com");
                    user.setPhone("13838389438");
                    user.setCreateDate(new Date());
                    return  user;
                @Override
                public User getObject(User user) {
                    user = new User();
                    user.setId(-405L);
                    user.setUsername("02-feignHystrixFallbackFactory");
                    user.setMail("hystrix-fallback@sina.com");
                    user.setPhone("13838389438");
                    user.setCreateDate(new Date());
                    return  user;
                @Override
                public User findUser(Long id) {
                    User user = new User();
                    user.setId(-406L);
                    user.setUsername("03-feignHystrixFallbackFactory");
                    user.setMail("hystrix-fallback@sina.com");
                    user.setPhone("13838389438");
                    user.setCreateDate(new Date());
                    return  user;
    

    其余配置与fallback一致。

    启动eureka 服务futurecloud-service,
    启动服务提供者服务futurecloud-user,
    启动此服务futurecloud-feign-hystrix
    访问http://localhost:8907/order/20 ,成功访问
    将服务futurecloud-user关掉,再一次访问http://localhost:8907/order/20,调用了fallbackFactory指定的FeignHystrixFallbackFactory中的方法。

    六、Hystrix的健康监测

    1. actuator

    ①添加依赖

    <!--添加认证监控-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    

    ②浏览器访问 http://192.168.215.2:8908/actuator/health

    就能显示Hystrix开启状态信息。

    有人说,Spring boot 2.x 使用了endpoint,导致/actuator/health,/actuator/hystrix.stream都无法访问,报404错误。
    我用的Spring Cloud 版本是Finchley.RELEASE,但是我没遇上,如果有人遇上,可以试试以下三种方法。而我将以下三种方法注释掉,一样能显示Hystrix的/actuator/health,/actuator/hystrix.stream信息

    设置让endpoint允许显示/actuator/health,/actuator/hystrix.stream信息的方法如下:
    方式一:在application.yml中添加如下配置:

    management:
      endpoint:
          health:    
            show-details: always   #允许显示/actuator/health信息
    
    management:
      endpoints:
          exposure:
            include: ["hystrix-stream"]   #允许显示/actuator/hystrix.stream信息
    
    management:
      endpoints:
          exposure:
            include: '*'   #允许显示所有信息,包括/actuator/health,/actuator/hystrix.stream
    

    解决方式二:在Hystrix监控项目的启动类中添加方法,设置允许显示的信息

    * 配置Hystrix ,使其显示健康监测信息 * @return @Bean public ServletRegistrationBean getServlet() { HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); registrationBean.setLoadOnStartup(1); registrationBean.addUrlMappings("/actuator/health","/actuator/hystrix.stream"); registrationBean.setName("HystrixMetricsStreamServlet"); return registrationBean;

    解决方式三:在application.yml中打开Feign 的Hystrix

    *************************************************************
    #开启hystrix配置
    feign:
      hystrix:
        enabled: true
    

    2. Hystrix-DashBoard的使用

    即前面说的/hystrix.stream 详细信息的图形化。

    ①引入依赖

            <!--添加hystrix dashboard依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
                <version>2.0.2.RELEASE</version>
            </dependency>
    

    ②在主函数上添加配置@EnableHystrixDashboard,开启Hystrix-DashBoard

    @SpringBootApplication
    @EnableHystrixDashboard //开启Hystrix-DashBoard
    public class FuturecloudHystrixDashBoardApplication
        public static void main( String[] args )
            SpringApplication.run(FuturecloudHystrixDashBoardApplication.class,args);
    

    ③配置文件增加endpoint

    management:
      endpoints:
          exposure:
            include: "*"
    

    ④访问入口

    http://localhost:8781/hystrix
    
    Hystrix Dashboard输入: http://localhost:8781/actuator/hystrix.stream 
    

    七. 补充

    一、hystrix参数使用方法

    @RestController
    public class MovieController {
      @Autowired
      private RestTemplate restTemplate;
      @GetMapping("/movie/{id}")
      @HystrixCommand(commandProperties = {
              @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"),
              @HystrixProperty(name = "execution.timeout.enabled", value = "false")},fallbackMethod = "findByIdFallback")
      public User findById(@PathVariable Long id) {
        return this.restTemplate.getForObject("http://microservice-provider-user/simple/" + id, User.class);
       * fallback方法
       * @param id
       * @return
      public User findByIdFallback(Long id) {
        User user = new User();
        user.setId(5L);
        return user;
    

    或者 application.yml

    feign: 
      hystrix: 
        enabled: true //feign开启hystrix支持【这里开启了,启动类就不用了】
    hystrix:
      command:
        default:
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 500 //线程超时,调用Fallback方法
          circuitBreaker:
            requestVolumeThreshold: 3  //10秒内出现3个以上请求(已临近阀值),并且出错率在50%以上,开启断路器.断开服务,调用Fallback方法
    

    二、hystrix参数如下

    **********参数类型**********
    hystrix.command.default和hystrix.threadpool.default中的default为默认CommandKey
    

    Command Properties

    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.errorThresholdPercentageMetrics相关参数
    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。