Hystrix 配置项讲解(一)

1. 前言

Hystrix 作为一款微服务监控与治理工具,针对与微服务复杂性的特点,其提供了很多与微服务监控和治理相关的配置项。通过在项目中配置这些配置项,可以很好地管理我们的微服务项目,对微服务的监控与治理都能起到一定的积极作用。

鉴于 Hystrix 配置项繁多的特点,所以我将 Hystrix 配置项的讲解分为了两个小节,分别是:基础配置项讲解、其他配置项讲解。本文会首先基于 Hystrix 的基础配置项进行详细地介绍。

本节主要内容:

  • Hystrix 配置项概览;

  • Hystrix 常用配置项注解详解。

希望同学们可以完全掌握本节内容。

2. Hystrix 配置项概览

Hystrix 的配置项分为,Hystrix 原生官网配置、整合 Spring Cloud 注解配置,这两种情况。前者适合学习原生 Hystrix 应用方法,但该类型配置项繁多,分不清主次,所以不适合新手学习;后者适合学习 Hystrix 与实际业务场景的应用,由于 Spring Cloud 对 Hystrix 的配置项进行了过滤,所以,新手学起来更简单。

鉴于此,本节会介绍整合了 Spring Cloud 框架的 Hystrix 各个配置项的基本定义,以及各个配置项的基本使用,初学者在学完本节内容之后,可以基本的来配置 Hystrix 。

接下来就让我们来看看都有哪些基础配置吧。

3. Hystrix 常用配置项注解详解

Hystrix 常用基础配置项注解如下表所示:

注解名称 适用位置 作用
@EnableHystrix 通知应用使用 Hystrix 熔断器
@EnableHystrixDashboard 通知应用使用 Hystrix 服务监控台
@HystrixCommand 方法 设置方法的服务容错机制
@HystrixProperty 方法 设置 Hystrix 中的参数
@HystrixCollapser 方法 合并请求

3.1 EnableHystrix 注解详解

@EnableHystrix 注解是在 Spring Cloud 框架中使用 Hystrix 的基础必须注解,即如果想要在 Spring Cloud 框架中使用 Hystrix ,就必须要先声明 @EnableHystrix 注解,来告诉 Spring Cloud 框架,你要在其中使用 Hystrix 了。

EnableHystrix 注解是作用在类上的注解,该注解没有任何参数,可以理解为,只是一个在 Spring Cloud 框架中来开启或关闭 Hystrix 的开关,具体用法我们看以下代码。

@EnableHystrix
public class DemoApplication {
    // 现在,同学们不需要理解main方法,重点看所使用的注解即可
	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}

代码解释:

第 1 行,我们将 @EnableHystrix 注解放到了 Spring Boot 项目的启动类上,这就表示,我们开启了 Hystrix ,即我们可以在项目中使用 Hystrix 了。

Tips: 在 Spring Boot 项目中,如果想使用 Hystrix ,就一定先要在项目的启动类上,添加上述注解,否则,即使将 Hystrix 的依赖引入到了项目中,也无法使用 Hystrix 及任何功能特性。

3.2 EnableHystrixDashboard 注解详解

@EnableHystrixDashboard 注解和 @EnableHystrix 注解的作用类似,即也可以理解为它是一个开关,用来控制在项目中是否使用 HstrixDasboard 服务监控台,如果声明了该注解,则表示使用 HstrixDasboard 服务监控台,否则,就不使用 HstrixDasboard 服务监控台。

@EnableHystrixDashboard 注解同样是作用在类上的注解,和 @EnableHystrix 注解不同的地方在于,该注解不是使用 Hystrix 所必须声明的注解,即在项目中你可以只使用 Hystrix 的功能特性,不使用它的 DashBoard 服务监控台,使用方法如下代码所示。

@EnableHystrixDashboard
public class DemoApplication {
    // 现在,同学们不需要理解main方法,重点看所使用的注解即可
	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}

Tips:
1. Hystrix Dashboard 服务监控台是否需要使用,一般是跟随项目要求来的,一般而言,任何一个项目都需要使用,因为不管是开发者,还是运维者,都需要在后台对服务进行监控;
2. Hystrix Dashboard 自带了很多我们需要用到的属性,通过查看这些属性,我们可以很清楚地了解每一个服务的健康情况,该服务监控台的使用会在后期有专门小节进行介绍,希望同学们可以持续关注。

3.3 HystrixCommand 注解详解

@HystrixCommand 注解,是 Hystrix 注解中的核心注解,可以说,只要想使用 Hystrix 的功能特性,就必须要使用该注解。

@HystrixCommand 注解提供了丰富的属性,来让我们配置 Hystrix 的功能特性,我将经常用到的属性汇总成了一个表格,如下表所示:

我们在了解了这些属性之后,就可以使用 HystrixCommand 属性来配置 Hystrix 的功能特性了。

属性名称 属性类型 默认值 作用
fallbackMethod String 空字符串 配置服务容错机制
defaultFallback String 空字符串 配置默认服务容错机制
threadPoolKey String 空字符串 配置线程池隔离策略
threadPoolProperties HystrixProperty[] 空数组 配置线程池详细策略

接下来,我们来看看这几个属性的详细信息

fallbackMethod 属性

该属性的作用就是配置项目中,服务的容错机制(什么是容错机制已在前面文章中有所介绍,这里不再赘述),我们直接看用法。

这里以一个简单的 helloWorld 请求为例,我们先来看正常请求。

@RequestMapping(value = "hello", method = RequestMethod.GET)
@ResponseBody
public String hello() {
    return "helloWorld";
}

代码解释:

第 1-2 行,我们使用 SpringBoot 中的注解,将请求暴露出去,即添加 helloWorld 请求的路径。

第 3-5 行,我们编写代码,实现 helloWorld 请求,其请求的响应结果是返回 helloWorld 字符串。

以上代码中,我们没有添加任何 Hystrix 的注解,只是一个很普通的正常请求,我们先来看下返回结结果。

请求返回结果

可以看到,请求已经正常返回了 helloWorld 。

接下来,让我们模拟以下请求错误的情况,即在请求时,我们认为设置一个延时时间,来让 Hystrix 捕捉到这一异常,并应用 Hystrix 的容错机制。

@RequestMapping(value = "hello", method = RequestMethod.GET)
@ResponseBody
@HystrixCommand(fallbackMethod = "helloFail")
public String hello() throws InterruptedException {
	Thread.sleep(1000);
    return "helloWorld";
}

public String helloFail(){
    return "helloFailed";
}

代码解释:

第 3 行,我们使用 HystrixCommand 注解的 fallbackMethod 属性来定义当请求不能正常响应时的应急方案,fallbackMethod 属性的值就是请求不能正常响应时,所返回的方法,这里的 helloFail 就是方法名。

第 5 行,我们手动加入了一个延时时间,该延时时间可以在响应请求时,延迟一秒响应,这就是我们手动实现的一个服务异常情况,该情况会被 Hystrix 的容错机制捕捉到。

第 9-11 行,我们编写代码,实现了一个当请求 helloWorld 失败时,所返回的应急方法,该方法返回 helloFailed 字符串。

以上代码中,我们加入了 Hystrix 的容错机制,让我们来看看效果。

请求响应失败

从上图中我们可以看到,我们还是请求的 helloWorld 请求,但是返回的确是 helloFailed ,这就表明,我们通过 HystrixCommand 注解的 fallbackMethod 属性来配置的服务容错起作用了。

defaultFallback 属性

defaultFallback 属性和 fallbackMethod 属性所实现的功能是基本相同的,只不过 defaultFallback 属性是用来配置默认的应急方法,即当我们的项目中存在多个应急方法时,我们给其中一个请求所配置的默认应急方法。

defaultFallback 属性所实现的效果和 fallbackMethod 属性是相同的,这里不再赘述。

threadPoolKey 和 threadPoolProperties属性

threadPoolKey 属性是用来配置线程池隔离策略的属性。

threadPoolProperties 属性,则是用来配置线程池详细策略的属性,例如,核心线程数量、最大线程数量等。

@RequestMapping(value = "hello", method = RequestMethod.GET)
@ResponseBody
@HystrixCommand(fallbackMethod = "helloFail", threadPoolKey = "HelloHystrix")
public String hello() throws InterruptedException {
	Thread.sleep(1000);
    return "helloWorld";
}

public String helloFail(){
    return "helloFailed";
}

第 3 行,我们使用 HystrixCommand 的 threadPoolKey 属性来配置线程池隔离,即我们将 helloWorld 请求划到了名为 HelloHystrix 的线程池下,这样就和主线程分离开了。

我们来看一下 threadPoolProperties 属性的具体用法。

@RequestMapping(value = "hello", method = RequestMethod.GET)
@ResponseBody
@HystrixCommand(fallbackMethod = "helloFail",  threadPoolProperties = {
            @HystrixProperty(name = "coresize", value = "2"),
            @HystrixProperty(name = "allowMaximumSizeToDivergeFromCoreSize", value = "true"),
            @HystrixProperty(name = "maximumSize", value = "2")
})
public String hello() throws InterruptedException {
	Thread.sleep(1000);
    return "helloWorld";
}

public String helloFail(){
    return "helloFailed";
}

代码解释:

第 4 行,我们为 threadPoolProperties 定义了几个常用的线程池隔离策略,它们分别是:核心线程数、开启最大线程数、最大线程数。至于还有哪些其他的配置项,由于不再本套课程内,同学们可以自行查阅资料了解。

Tips:
1. 在实际工作中,defaultFallback 属性相对而言很少会用到,一般会手动使用 fallbackMethod 属性来直接指定相关请求所对应的应急方法;
2. threadPoolProperties 属性经常使用,这里只是将最经常使用的几个配置策略给同学们做了介绍,剩下不常用的希望同学们可以自行查阅了解;
3. 在使用 threadPoolProperties 属性时,如果我们的核心线程数量和最大线程数量相等,此时又有超过该数量的请求来请求服务了,那么,在这种情况下,请一定要配置 Hystrix 的降级策略,否则,后台服务会直接报错。

3.4 HystrixProperty 注解详解

@HystrixProperty 注解其实是一个辅助配置注解,他的主要作用就是对参数配置场景下,对每个配置策略进行单独的声明,他的用法就是上述 threadPoolProperties 属性所配置的那样。

@HystrixProperty 注解只有两个属性,分别是 name 和 value ,name 的值是 Hystrix 官网定义好的配置项的 key ,而 value 值则是配置对应的具体参数值。

@HystrixProperty 注解中 name 属性的描述不能随意描述,要根据官网所定义的配置项来描述,不可无中生有。

3.5 HystrixCollapser 注解详解

@HystrixCollapser 注解在 Spring Cloud 中,发挥着重要的作用。我们可以把他简单理解为:它是可以进行请求合并的注解,什么是请求合并呢?

正常情况下,我们的每一个请求都会请求到我们的服务中,且最后服务会返回给我们对应的响应结果,如果我们存在多个请求,且每个请求都是一样的,在这种情况,我们的服务也是一个请求一个请求的去处理,很是浪费资源。

针对于上述这种再正常不过的情况,Hystrix 对此做了很好地优化。当有多个相同的请求来请求我们的服务时,Hystrix 会将这些请求进行合并,并最终实现多个相同请求请求服务,服务只接收一次请求的目的,这就是请求合并。

请求合并相对于传统请求处理而言,大大节省了服务器的资源消耗,降低了服务器的使用和维护成本。在微服务项目中,使用请求合并功能,已经成了业界主流的方案。

接下来,先让我们看一下,HystrixCollapser 注解中都有哪些属性。

collapserKey 属性,即请求合并时的 key ,字符串类型,默认是 HystrixCollapser 注解所应用的方法名。

batchMethod 属性,需要使用请求合并功能的方法,字符串类型,值是需要使用请求合并功能的方法名。

scope 属性,即请求合并的作用范围,Scope 类型,默认只作用在当前请求下,可以设置成全局响应。

collapserProperties 属性,即请求合并的详细配置策略,HystrixProperty 数组类型,其内容为 Hystrix 官网所规定内容,使用方法同上 HystrixProperty 注解使用方法。

最后,我们使用官网的一个例子,来介绍一下 HystrixCollapser 注解如何使用。

@HystrixCollapser(batchMethod = "getUserByIds")
public List<User> getUserById(String id) {
    return null;
}

@HystrixCommand(fallbackMethod = "getUserByIdsFail")
public List<List<User>> getUserByIds(List<String> ids) {
List<List<User>> users = new ArrayList<User>();
    for (String id : ids) {
        users.add(new User(id, "name: " + id));
    }
    return users;
 }

代码解释:

第 1 行,我们使用 HystrixCollapser 注解的 batchMethod 属性,来指定需要使用请求合并的方法。

第 6 行,我们使用 HystrixCommand 注解的 fallbackMethod 属性,来指定 getUserByIds 方法请求失败时所返回的应急方法。

Tips:
1. 使用 HystrixCollapser 注解时,其注解作用的方法的返回类型,必须是 list 类型,这是 Hystrix 的规定,所以,上述代码中 getUserById 的方法的返回值是一个 User 类型的 list ;
2. 使用 HystrixCollapser 注解时,必须要搭配 HystrixCommand 注解,来配置对应请求的应急方法,这也是 Hystrix 所规定的,所以,上述代码中我们在 getUserByIds 方法上定义了应急方法;
3. HystrixCollapser 注解在实际工作中经常使用,是提升项目吞吐量最简单、最直接的配置。

4. 小结

本节内容概览

本小节通过图文并茂的方式,为大家介绍了 Hystrix 整合 Spring Cloud 后的基础常用配置项,基本上,在 Spring Cloud 框架中的体现方式均已注解方式进行体现。针对在配置过程中,可能会遇到的坑,做了专门的提示;针对在实际工作中经常使用的注解,做了重点讲解和应用剖析,旨在帮助同学们能够系统性的应用这些基础注解,打好 Hystrix 的配置基础。