spring cloud / netflix hystrix 客户端弹性

客户端弹性

所谓客户端弹性(resiliency),指的是当依赖的服务发生错误或表现不佳时,客户端仍然能够有应对的办法,而不是陷入崩溃或不可用。

本篇将讨论如何通过Hystrix来实现

  • 熔断 (circuit breaker)
  • 降级 (fallback)
  • 隔离 (bulkhead)

引入Hystrix

借助spring cloud,程序员引入Hystrix只需三步

1、首先加入maven依赖


    org.springframework.cloud
    spring-cloud-starter-netflix-hystrix

2、在启动类中加入@EnableCircuitBreaker注解

@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
public class EurekaClientApplication {

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

3、使用@HystrixCommand标记一个方法,例如:

@GetMapping("/call")
@HystrixCommand
public String call() {
    String url = "http://myservice1/service1";
    ResponseEntity responseEntity = restTemplate.getForEntity(url, String.class);
    return responseEntity.getBody();
}

熔断 (circuit breaker)

@HystrixCommand并不限于Http调用,它可以用于任何请求资源的方法。当在一个方法上加了这个注解后,Hystrix将会自动生成一个代理类,该代理将包装该方法,并通过专门用于处理远程调用的线程池来管理对该方法的所有调用。当出现以下情况时,熔断器将会生效

  • 返回结果超时
  • Http接口返回500
  • 方法抛出异常

超时的默认时间是1秒中。如果上述接口的响应时间是5秒的话,每次请求该接口,熔断器都会在1秒后拒绝继续等待,并返回错误结果。可以通过下面的方式来修改默认的超时时间

@HystrixCommand(
    commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000") }
)

降级 (fallback)

从fallback的字面意思来看,是当某个接口不能正常提供服务时的一种备用机制,可以理解为服务降级。例如一个推荐系统,正常情况下我会针对一个用户的具体情况来做推荐,但如果由于对应的接口不能正常提供服务,可以考虑使用别的方式来推荐一些不那么个性化的内容

使用Hystrix来实现的话,就是提供另外一个备用的方法,当熔断器触发后,会自动调用备用方法。下面是一个例子

@GetMapping("/call")
@HystrixCommand(fallbackMethod = "callFallBack")
public String call() {
    String url = "http://myservice1/service1";
    ResponseEntity responseEntity = restTemplate.getForEntity(url, String.class);
    return responseEntity.getBody();
}

public String callFallBack() {
    return "fall back result";
}

通过fallbackMethod = "callFallBack"指定了一个备用方法,备用方法必须与@HystrixCommand标注的方法拥有相同的参数列表和返回值

隔离 (bulkhead)

当服务依赖的某个外部资源不能很好地工作,有可能会拖垮整个服务本身,为了避免这种事情的发生,可以使用资源隔离的机制。

Hystrix实现隔离的机制是,将某个或某几个熔断器放到指定的线程池中,并限制线程池的资源。

@HystrixCommand(
    threadPoolKey = "myThreadPool", 
    threadPoolProperties = {
        @HystrixProperty(name = "coreSize", value = "30"),
        @HystrixProperty(name = "maxQueueSize", value = "10") 
    }
)

通过threadPoolKey属性为特定的熔断器设置一个专用的线程池,并通过threadPoolProperties指定若干个线程池属性,可以对某类外部资源的调用起到隔离的作用。

Hystrix在调用失败后的决策过程

spring cloud / netflix hystrix 客户端弹性_第1张图片

上图是Hystrix在遇到调用失败后的决策过程

每当Hystrix命令遇到服务错误时,它将开始一个10s(变量1)的计时器,用于检查服务调用失败的频率,如果在10s内的调用总次数达到了20(变量2),并且失败的比例超过了50%(变量3),Hystrix将触发熔断器,让接下来的几乎所有请求都快速失败,但每隔5s(变量4)都会让一个调用去尝试。如果发现某次尝试的Hystrix命令可以正常执行了,就恢复这个熔断器。

以上用括号括起来的4个变量都是可以配置的

  • 变量1:metrics.rollingStats.timeInMilliseconds
  • 变量2:circuitBreaker.requestVolumeThreshold
  • 变量3:circuitBreaker.sleepWindowInMilliseconds
  • 变量4:circuitBreaker.errorThresholdPercentage

设置的方式如下:

@HystrixCommand(
    threadPoolKey = "licenseByOrgThreadPool", 
    threadPoolProperties = {
        @HystrixProperty(name = "coreSize", value = "30"),
        @HystrixProperty(name = "maxQueueSize", value = "10") 
    },
    commandProperties ={
        @HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value="10"),
        @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value="75"),
        @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value="7000"),
        @HystrixProperty(name="metrics.rollingStats.timeInMilliseconds",value="15000")
    }
)

完整的列表请参考 https://github.com/Netflix/Hystrix/wiki/Configuration

配置Class级别的Hystrix属性

可以使用@DefaultProperties在class级别配置一些默认的commandProperties,这些属性值将会被应用到当前class下的所有@HystrixCommandcommandProperties中,但具体的@HystrixCommand仍然可以显式地覆盖

@DefaultProperties(
    commandProperties ={
        @HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value="10")
    }
)
public class myClass{
    ...
}

你可能感兴趣的:(hystrix,spring,cloud,spring,cloud)