SpringBoot精选SpringCloudJava

SpringCloud组件之Hystrix

2019-07-02  本文已影响1人  阿靖哦

在分布式环境中,许多服务依赖项中的一些必然会失败。Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助你控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、停止级联失败和提供回退选项来实现这一点,所有这些都可以提高系统的整体弹性

hystrix.jpg

一、Hystrix宗旨和工作原理

Hystrix的宗旨:

Hystrix工作原理

info.png
当需要完成某项任务时,通过 Hystrix 将任务包裹起来,交由 Hystrix 来完成任务,从而享受 Hystrix 带来保护

Hystrix 提供了两个Command, HystrixCommand 和 HystrixObservableCommand,可以使用这两个对象来包裹待执行的任务,Hystrix应用自己的一系列保护机制,在执行用户任务的各节点(执行前、执行后、异常、超时等)做一系列的事情

  • R execute():同步执行,从依赖服务得到单一结果对象
  • Future<R> queue():异步执行,返回一个 Future 以便获取执行结果,也是单一结果对象
  • Observable<R> observe():hot observable,创建Observable后会订阅Observable,可以返回多个结果
  • Observable<R> toObservable():cold observable,返回一个Observable,只有订阅时才会执行,可以返回多个结果

如果启用了 Hystrix Cache,任务执行前将先判断是否有相同命令执行的缓存。如果有则直接返回缓存的结果;如果没有缓存的结果,但启动了缓存,将缓存本次执行结果以供后续使用

断路器(circuit-breaker)和保险丝类似,保险丝在发生危险时将会烧断以保护电路,而断路器可以在达到我们设定的阀值时触发短路(比如请求失败率达到50%),拒绝执行任何请求。如果断路器被打开,Hystrix 将不会执行命令,直接进入Fallback处理逻辑

Hystrix 隔离方式有线程池隔离和信号量隔离。当使用Hystrix线程池时,Hystrix 默认为每个依赖服务分配10个线程,当10个线程都繁忙时,将拒绝执行命令。信号量同理

通过HystrixObservableCommand.construct()或者HystrixCommand.run()来运行用户真正的任务

每次开始执行command、结束执行command以及发生异常等情况时,都会记录执行情况,例如:成功、失败、拒绝以及超时等情况,会定期处理这些数据,再根据设定的条件来判断是否开启断路器

在命令失败时执行用户指定的 Fallback 逻辑。上图中的断路、线程池拒绝、信号量拒绝、执行执行、执行超时都会进入 Fallback 处理

原始结果将以Observable形式返回,在返回给用户之前,会根据调用方式的不同做一些处理

更多详细的工作原理,可前往: How is Works

二、HystrixCommand注解

我们的配置都是基于 HystrixCommand 的,我们通过在方法上添加 @HystrixCommand 注解并配置注解的参数来实现配置,但有的时候一个类里面会有多个 Hystrix 方法,每个方法都是类似配置的话会冗余很多代码,这时候我们可以在类上使用 @DefaultProperties 注解来给整个类的 Hystrix 方法设置一个默认值。
参数介绍

三、hystrix配置属性详解

Hystrix配置属性详解,所有属性默认都是default,如需针对某个服务,将default改为那个服务名即可

  1. Execution:控制HystrixCommand.run()如何运行
  2. Fallback:控制HystrixCommand.getFallback()如何运行
  3. Circuit Breadker:控制断路器的行为
  4. Metrics:捕获HystrixCommand和HystrixObervableCommand执行消息相关的配置属性
  5. Request Context:设置请求上下文的属性
  6. Collapser Properties:设置请求合并的属性
  7. Thread Pool Properties:设置线程池的属性

1、Execution

在默认情况下,推荐HystrixCommands 使用 thread 隔离策略,HystrixObservableCommand 使用 semaphore 隔离策略。 只有在高并发(单个实例每秒达到几百个调用)的调用时,才需要修改HystrixCommands 的隔离策略为semaphore 。semaphore 隔离策略通常只用于非网络调用

hystrix.command.default.execution.isolation.strategy=
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=
hystrix.command.default.execution.isolation.thread.interruptOnTimeout=
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests=
hystrix.command.default.execution.isolation.thread.interruptOnCancel=

2、Fallback

以下属性控制HystrixCommand.getFallback() 如何执行。这些属性对隔离策略THREAD 和SEMAPHORE都起作用

hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests=
hystrix.command.default.fallback.enabled=

3、Circuit Breaker

控制断路器的行为

hystrix.command.default.circuitBreaker.enabled=
hystrix.command.default.circuitBreaker.requestVolumeThreshold=
hystrix.command.default.circuitBreaker=
hystrix.command.default.circuitBreaker.forceOpen=
hystrix.command.default.circuitBreaker.forceClosed=

4、Mertrics

捕获和HystrixCommand 和 HystrixObservableCommand 执行信息相关的配置属性

hystrix.command.default.metrics.rollingStats.timeInMilliseconds=
hystrix.command.default.metrics.rollingStats.numBuckets=
hystrix.command.default.metrics.rollingPercentile.enabled=
hystrix.command.default.metrics.rollingPercentile.timeInMilliseconds=
hystrix.command.default.metrics.rollingPercentile.numBuckets=
hystrix.command.default.metrics.rollingPercentile.bucketSize=
hystrix.command.default.metrics.healthSnapshot.intervalInMilliseconds=

5、Request Context

此属性控制HystrixCommand使用到的Hystrix的上下文

hystrix.command.default.requestCache.enabled=
hystrix.command.default.requestLog.enabled=

6、Collapser Properties

设置请求合并的属性

hystrix.collapser.default.maxRequestsInBatch=
hystrix.collapser.default.timerDelayInMilliseconds=
hystrix.collapser.default.requestCache.enabled=

7、Thread Pool Properties

设置Hystrix Commands的线程池行为,大部分情况线程数量是10。线程池数量的计算公式如下:最高峰时每秒的请求数量 × 99%命令执行时间 + 喘息空间,设置线程池数量的主要原则是保持线程池越小越好,因为它是减轻负载并防止资源在延迟发生时被阻塞的主要工具

hystrix.threadpool.default.coreSize=
hystrix.threadpool.default.maximumSize=
hystrix.threadpool.default.maxQueueSize=
hystrix.threadpool.default.queueSizeRejectionThreshold=
hystrix.threadpool.default.keepAliveTimeMinutes=
hystrix.threadpool.default.allowMaximumSizeToDivergeFromCoreSize=
hystrix.threadpool.default.metrics.rollingStats.timeInMilliseconds=
hystrix.threadpool.default.metrics.rollingStats.numBuckets=

四、Hystrix的使用

1、导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
    <groupId>cn.gjing</groupId>
    <artifactId>tools-httpclient</artifactId>
    <version>1.0.2</version>
</dependency>

2、启动类标注注解

/**
 * @author Gjing
 */
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class HystrixApplication {

    public static void main(String[] args) {
        SpringApplication.run(HystrixApplication.class, args);
    }
}

3、编写service

@Service
public class TestService {

     // 此注解说明该方法要执行回退,fallback指定回退方法
    @HystrixCommand(fallbackMethod = "defaultFallback")
    public String hello() {
        HttpClient httpClient = new HttpClient();
        return httpClient.get("http://127.0.0.1:8090/test2", String.class);
    }

    // 回退方法
    public String defaultFallback() {
        return "no hello";
    }
}

4、编写Controller进行测试

/**
 * @author Gjing
 **/
@RestController
public class TestController {

    @Resource
    private TestService testService;

    @PostMapping("/test")
    public String test() {
        return testService.hello();
    }
}

5、目标服务的接口

因为hystrix默认超时是1秒,所以,我们在目标服务,加个线程休眠,大于1秒即可

/**
 * @author Gjing
 **/
@RestController
public class DemoController {

    @GetMapping("/test2")
    public String test2() throws InterruptedException {
        Thread.sleep(1000);
        return "ok";
    }
}

5、测试

超时进入回退方法,并返回了回退方法里的内容

1562046883(1).jpg

三、Feign使用Hystrix

1、增加依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2、启动类增加@EnableFeignClients注解

3、增加一个service和回退类

/**
 * @author Gjing
 * name为目标服务名,fallback为回退类
 **/
@FeignClient(name = "demo",fallback = FeignServiceFallbackImpl.class)
public interface FeignService {

    @RequestMapping(value = "/test2", method = RequestMethod.GET)
    String  test2();
}

/**
 * 回退类,实现feignService
 */
@Component
class FeignServiceFallbackImpl implements FeignService{
    @Override
    public String test2() {
        return "啊哦,出错了");
    }
}

4、编写Controller进行测试

/**
 * @author Gjing
 **/
@RestController
public class FeignController {

    @Resource
    private FeignService feignService;

    @PostMapping("/testFeign")
    public String testFeign() {
        return feignService.test();
    }
}

如果出错了,会进行回退

erro.jpg

四、使用监控面板dashBoard

1、增加依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2、启动类加上注解@EnableHystrixDashboard

3、配置文件

server:
  port: 8082
spring:
  application:
    name: hystrix-demo
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
# feign使用hystrix进行回退
feign:
  hystrix:
    enabled: true
# 端点管理 hystrixDashboard
management:
  endpoints:
    web:
      exposure:
        include: "*"

4、启动项目,并访问http://localhost:port/hystrix即可打开如下页面

d.jpg
通过主页面的文字介绍,可以知道,共支持三种不同的监控方式*

本文只讲解单体应用,因此我们在主页面输入http://localhost:8082/actuator/hystrix.stream即可访问,请求几次结果

re.jpg

界面解释

11

到此本文就结束了,篇幅较长,如哪里有字写错或单词打错,各位帮忙纠正,本项目源码:SpringCloud-Demo

上一篇下一篇

猜你喜欢

热点阅读