熔断器

雪崩效应

基础服务的故障可能会导致级联故障, 进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应。服务雪崩效应是一种因“服务提供者”的不可用导致“服务消费者”的不可用,并将不可用逐渐放大的过程

202036163154

请求堆积

在大量请求到来时,处理器有一个线程池来处理请求,当请求到达量远远大于处理量,请求就会在线程池中堆积,从而导致大量请求被阻塞

服务隔离

当有故障发生时,能将问题和影响隔离在某个模块内部,而不扩散风险,不波及其它模块,不影响整体的系统服务

服务降级

当调用的服务不可用时,服务调用方不会继续等待,而是(服务调用方)使用一个预设好的结果返回

服务熔断

一般是某个服务故障或者是异常引起的,类似现实世界中的‘保险丝’,当某个异常条件(通常是请求量过高)被触发,直接熔断整个服务,而不是一直等到此服务超时

Hystrix

  • 断路器机制

当Hystrix Command请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open). 这时所有请求会直接失败而不会发送到后端服务.

断路器保持在开路状态一段时间后(默认5秒), 自动切换到半开路状态(HALF-OPEN).

这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回闭路状态(CLOSED), 否则重新切换到开路状态(OPEN)

202032210372

统计器(Metrics) :滑动窗口(metrics.rollingStats.timeInMilliseconds)以及桶(metrics.rollingStats.numBuckets)

Hystrix 并不是只要有一条请求经过就去统计,而是将整个滑动窗口均分为 numBuckets 份,时间每经过一份就去统计一次。在经过一个时间窗口后,才会判断断路器状态要不要开启

  • Fallback

相当于是降级操作. 对于查询操作, 我们可以实现一个fallback方法, 当请求后端服务出现异常的时候, 可以使用fallback方法返回的值. fallback方法的返回值一般是设置的默认值或者来自缓存

  • 资源隔离

在Hystrix中, 主要通过线程池来实现资源隔离. 通常在使用的时候我们会根据调用的远程服务划分出多个线程池 每个外部依赖用一个单独的线程池,这样的话,如果对那个外部依赖调用延迟很严重,最多就是耗尽那个依赖自己的线程池而已,不会影响其他的依赖调用

线程池机制的缺点

  • 多了一些管理线程,增加了CPU的开销

整体流程

202032210318

添加熔断机制

熔断只是作用在服务调用这一端

  • 开启配置
feign.hystrix.enabled=true
  • 编写fallback
@Component
public class HelloRemoteHystrix implements HelloRemote {
    @Override
    public String hello(String name) {
        return "sorry,service call failed";
    }
}
  • 在远程调用接口上添加fallback
@FeignClient(value = "producer",fallback = HelloRemoteHystrix.class)
public interface HelloRemote {
    @RequestMapping("/hello")
    String hello(@RequestParam String name);
}

这样一旦producer挂掉了,将会返回默认结果

添加服务隔离机制

  • 引入依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
@RequestMapping("/user")
// 添加这个注解之后,hystrix会开启服务隔离,访问这个接口的线程独属于某一个线程池
@HystrixCommand
public String user(){
    return restTemplate.getForObject("http://user-service/user",String.class);
}

接口添加@HystrixCommand这个注解之后,该接口默认的超时时间是1秒,需要设置超时时间,否则超时后hystrix会抛出一个异常,不会等到fegin返回

  • 超时时间
@RequestMapping("/user")
@HystrixCommand(commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")})
public String user(){
    return restTemplate.getForObject("http://user-service/user",String.class);
}

信号量隔离

hystrix有两种隔离方式,线程池和信号量 线程池通过线程池来实现限流的,信号量则是通过维护一个计数器来限制

一些概念

  • command key
    • 代表了一类 command,一般来说,代表了下游依赖服务的某个接口
  • command group
    • 默认情况下,就是通过 command group 来定义一个线程池的,而且还会通过 command group 来聚合一些监控和报警信息,同一个 command group 中的请求,都会进入同一个线程池中

熔断监控 Hystrix-dashboard

通过Hystrix Dashboard我们可以在直观地看到各Hystrix Command的请求响应时间, 请求成功率等数据

单个应用的熔断监控

  • 添加依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<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>
  • 打开自动配置
@EnableCircuitBreaker
@EnableHystrixDashboard
  • 如果发生404则添加如下配置
@Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
  • 访问

http://127.0.0.1:10000/hystrix/

Turbine

  • 添加依赖
        <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>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-turbine</artifactId>
        </dependency>
  • 配置
spring.application.name=hystrix-dashboard-turbine
server.port=11000
turbine.appConfig=node1,node2

turbine.aggregator.clusterConfig= default
turbine.clusterNameExpression= new String("default")

eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
@EnableTurbine
@EnableHystrixDashboard

批注 2019-07-24 155313

results matching " "

No results matching " "

results matching " "

No results matching " "