《深入理解 Spring Cloud 与微服务构建》第九章 熔断器 Hystrix

文章目录

  • 《深入理解 Spring Cloud 与微服务构建》第九章 熔断器 Hystrix
  • 一、Hystrix 简介
  • 二、Hystrix 解决的问题
  • 三、Hystrix 的设计原则
  • 四、Hystrix 的工作机制
  • 五、在 RestTemplate 和 Ribbon 上使用熔断器
  • 六、在 Feign 上使用熔断器
  • 七、使用 Hystrix Dashboard 监控熔断器的状态
    • 1.在 RestTemplate 中使用 Hystrix Dashboard
    • 2.在 Feign 中使用 Hystrix Dashboard
  • 八、使用 Turbine 聚合监控

一、Hystrix 简介

在分布式系统中,服务与服务之间的依赖错综复杂,一种不可避免的情况就是某些服务会出现故障,导致依赖于它们的其他服务出现远程调度的线程阻塞。Hystrix 是 Netflix 公司开源的一个项目,它提供了熔断器功能,能够阻止分布式系统中出现联动故障。Hystrix 是通过隔离服务的访问点阻止联动故障的,并提供了故障的解决方案,从而提高了整个分布式系统的弹性

二、Hystrix 解决的问题

在复杂的分布式系统中,可能有几十个服务相互依赖,这些服务由于某些原因,例如机房的不可靠性、网络服务商的不可靠性等,导致某个服务不可用。如果系统不隔离该不可用的服务,可能会导致整个系统不可用

例如,对于依赖 30 个服务的应用程序,每个服务的正常运行时间为 99.99%,对于单个服务来说,99.99% 的可用是非常完美的。但是如果系统中有 30 个服务互相之间有依赖关系,那么就要对 99.99% 进行 30 次乘方,也就是 99.7%.这表明整个系统只有 99.7% 的时间是正常运行的,具体来说,10 亿次请求中有300 万次失败,实际情况可能更糟糕。因此,如果不提高整个系统的韧性,即使所有依赖关系都表现良好,单个服务只有 0.01% 的不可用,由于整个系统的服务相互依赖,最终对整个系统的影响还是非常大的

在高并发的情况下,单个服务的延迟会导致整个请求都处于阻塞状态,最终的结果就是整个服务的线程资源消耗殆尽。服务的依赖性会导致依赖于该故障服务的其它服务也处于线程阻塞状态,最终导致这些服务的线程资源消耗殆尽,直到不可用,从而导致整个微服务系统都不可用,即雪崩效应

为了防止雪崩效应,因而产生了熔断器模型。Hystrix 是在业界表现非常好的一个熔断器模型实现的开源组件,它是 Spring Cloud 组件不缺少的一部分

三、Hystrix 的设计原则

  • 防止单个服务的故障耗尽整个服务的 Servlet 容器(例如 Tomcat) 的线程资源
  • 快速失败机制,如果某个服务出现了故障,则调用该服务的请求快速失败,而不是线程等
  • 提供回退(fallback)方案,在请求发生故障时,提供设定好的回退方案
  • 使用熔断机制,防止故障扩散到其他服务
  • 提供熔断器的监控组件 Hystrix Dashboard,可以实时监控熔断器的状态

四、Hystrix 的工作机制

首先,当服务的某个 API 接口的失败次数在一定时间内小于设定的阈值时,熔断器处于关闭状态,该 API 接口正常提供服务。当该 API 接口处理请求的失败次数大于设定的阈值时,Hystrix 判定该 API 接口出现了故障,打开熔断器,这时请求该 API 接口会执行快速失败的逻辑(即 fallback 回退的逻辑),不执行业务逻辑,请求的线程不会处于阻塞状态。处于打开状态的熔断器在一段时间后会处于半打开状态,并将一定数量的请求执行正常逻辑。剩余的请求会执行快速失败,若执行正常逻辑的请求失败了,则熔断器继续打开;若成功了,则将熔断器关闭。这样熔断器就具有了自我修复的能力

五、在 RestTemplate 和 Ribbon 上使用熔断器

在之前的 eureka-ribbon-client 工程中,我们使用 RestTemplate 调用了 eureka-client 的 “/hi” API 接口,并用 Ribbon 做了负载均衡,本案例在此基础上增加 Hystrix 熔断器的功能

首先在工程的 pom 文件中引用 Hystrix 的起步依赖 spring-cloud-starter-hystrix,代码如下:

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

然后在 Spring Boot 的启动类 EurekaRibbonClientApplication 加上 @EnableHystrix 注解开启 Hystrix 的熔断器功能

修改 RibbonService 的代码,在 hi() 方法上加 @HystrixCommand 注解。有了 @HystrixCommand 注解,hi() 方法就启用 Hystrix 熔断器的功能,其中,fallbackMethod 为处理回退(fallback)逻辑的方法。在本例中,直接返回了一个字符串。在熔断器打开的状态下,会执行 fallback 逻辑。fallback 的逻辑最好是返回一些静态的字符串,不需要处理复杂的逻辑,也不需要远程调度其它服务,这样方便执行快速失败,释放线程资源。如果一定要在 fallback 逻辑中远程调度其它服务,最好在远程调度其它服务时,也加上熔断器。案例代码如下:

package com.sisyphus.service;import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.ribbon.proxy.annotation.Hystrix;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;@Service
public class RibbonService {@AutowiredRestTemplate restTemplate;@HystrixCommand(fallbackMethod = "hiError")public String hi(String name){return restTemplate.getForObject("http://eureka-client/hi?name=" + name, String.class);}public String hiError(String name){return "hi " + name + ",sorry,error!";}
}

依次启动工程 eureka-server、eureka-client 和 eureka-ribbon-client。等所有的工程都启动完毕,在浏览器上访问 http://localhost:8764/hi,浏览器会显示

hi sisyphus,i am from port:8763

关闭 eureka-client,即它处于不可用的状态,此时 eureka-ribbon-client 无法调用 eureka-client 的 “/hi” 接口,访问 http:localhost:8764/hi,浏览器会显示:

hi sisyphus,sorry,error!

由此可见,当 eureka-client 不可用时,调用 eureka-ribbon-client 的 “/hi” 接口会进入 RibbonService 类的 “/hi” 方法中。由于 eureka-client 没有响应,判定 eureka-client 不可用,开启了熔断器,最后进入了 fallbackMethod 的逻辑。当熔断器打开了,之后的请求会直接执行 fallbackMethod 的逻辑。这样做的好处就是通过快速失败,请求能够得到及时处理,线程不再阻塞

六、在 Feign 上使用熔断器

由于 Feign 的起步依赖中已经引入了 Hystrix 的依赖,所以在 Feign 中使用 Hystrix 不需要引入任何的依赖。只需要在 eureka-feign-client 工程的配置文件 application.yml 中配置开启 Hystrix 的功能,配置文件 application.yml 中加入以下配置:

feign:hystrix:enabled: true

然后修改 eureka-feign-client 工程中的 EurekaClientFeign 代码,在 @FeignClient 注解的 fallback 配置加上快速失败的处理类。该处理类是作为 Feign 熔断器的逻辑处理类,必须实现被 @FeignClient。例如案例中的 Hystrix 类实现了接口 EurekaClientFeign,最后需要以 Spring Bean 的形式注入 IoC 容器中。代码如下:

package com.sisyphus.feign;import com.sisyphus.config.FeignConfig;
import com.sisyphus.hystrix.HiHystrix;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;@FeignClient(value = "eureka-client", configuration =  FeignConfig.class, fallback = HiHystrix.class)
public interface EurekaClientFeign {@GetMapping(value = "/hi")String sayHiFromClientEureka(@RequestParam(value = "name") String name);
}

HiHystrix 作为熔断器的逻辑处理类,需要实现 EurekaClientFeign 接口,并需要在接口方法 sayHiFromClientEureka() 里写处理熔断的具体逻辑,同时还需要再 HiHystrix 类上加 @Component 注解,注入 IoC 容器中。代码如下:

package com.sisyphus.hystrix;import com.sisyphus.feign.EurekaClientFeign;
import org.springframework.stereotype.Component;@Component
public class HiHystrix implements EurekaClientFeign {@Overridepublic String sayHiFromClientEureka(String name) {return "hi " + name + ",sorry,error!";}
}

依次启动工程 eureka-server、eureka-client 和 eureka-feign-client。在浏览器上访问 http://localhost:8765/hi,浏览器会显示:

hi sisyphus,i am from port:8763

关闭 eureka-client,即它处于不可用的状态,此时 eureka-feign-client 无法调用 eureka-client 的 “/hi” 接口,在浏览器上访问 http://localhost:8765/hi,浏览器会显示

hi sisyphus,sorry,erroe!

由此可见,当 eureka-client 不可用时,eureka-feign-client 进入了 fallback 的逻辑处理类(即 HiHystrix),由这个类来执行熔断器打开时的处理逻辑

七、使用 Hystrix Dashboard 监控熔断器的状态

熔断器的状况反映了一个程序的可用性和健壮性,是一个重要指标。Hystrix Dashboard 是监控 Hystrix 的熔断器状况的一个组件,提供了数据监控和友好的图形化展示界面。本节在上一节的基础上,以案例的形式讲述如何使用 Hystrix Dashboard 监控熔断器的状态

1.在 RestTemplate 中使用 Hystrix Dashboard

改造上面的工程,首先在 eureka-ribbon-client 工程的 pom 文件中加上 Actuator 的起步依赖和 Hystrix Dashboard 的起步依赖。代码如下:

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

在程序的启动类 EurekaRibbonClientApplication 加上 @EnableHystrixDashboard 开启 Hystrix Dashboard 的功能

在 application.yml 配置文件中开启 hystrix.stream 端点:

management:endpoints:web:exposure:include: hystrix.stream

依次启动工程 eureka-server、eureka-client 和 eureka-ribbon-client,在浏览器上访问 http://localhost:8764/hi

然后在浏览器上访问 http:localhost:8764/actuator/hystrix.stream,浏览器上会显示熔断器的数据指标;

在浏览器上访问 http://localhost:8764/hystrix,浏览器显示的界面如图所示:


在界面上的三个文本框中依次填写 http://localhost:8764/actuator/hystrix.stream、2000、sisyphus,单击 “Monitor Stream” 按钮,进入页面:

该页面显示了熔断器的各种数据指标,这些数据指标所表示的含义如图所示:


线程池的监视器说明:

2.在 Feign 中使用 Hystrix Dashboard

同 eureka-ribbon-client 类似,eureka-feign-client 工程的 pom 文件需要加上 Actuator、Hystrix 和 Hystrix Dashboard 的起步依赖。Feign 虽然自带了 Hystrix,但是并不包含起步依赖

同样,在启动类上添加注解 @EnableHystrix 和 @EnableHystrixDashboard,以及在 application.yml 配置文件中开启 hystrix.stream 端点

只需要上述两部就可以在 Feign 中开启 Hystrix Dashboard 的功能,在浏览器中打开 Dashboard 的操作也大同小异

八、使用 Turbine 聚合监控

在使用 Hystrix Dashboard 组件监控服务的熔断器状况时,每个服务都有一个 Hystrix Dashboard 主页,当服务数量很多时,监控非常不方便。为了同时监控多个服务的熔断器的状况,Netflix 开源了 Hystrix 的另一个组件 Turbine。Turbine 用于聚合多个 Hystrix Dashboard,将多个 Hystrix Dashboard 组件的数据放在一个页面上展示,进行集中监控

在上一节的例子上继续进行改造,在主 Maven 工程下新建一个 Module 工程,作为 Turbine 聚合监控的工程,取名为 eureka-monitor-client。首先,在工程的 pom 文件引入工程所需的依赖,包括 hystrix dashboard、turbine、actuator 和 test 的起步依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>Eureka</artifactId><groupId>org.sisyphus</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>eureka-monitor-client</artifactId><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-turbine</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency></dependencies></project>

接着配置启动类,开启相关功能:

package com.sisyphus;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.turbine.EnableTurbine;@SpringBootApplication
@EnableEurekaClient
@EnableTurbine
public class EurekaMonitorClientApplication {public static void main(String[] args) {SpringApplication.run(EurekaMonitorClientApplication.class, args);}
}

然后在工程的配置文件 application.yml 中加上相关的配置,具体的配置代码如下:

spring:application:name: service-turbineserver:port: 8769turbine:combine-host-port: trueapp-config: eureka-ribbon-client,eureka-feign-clientcluster-nameexpression: new String("default")aggregator:cluster-config: defaulteureka:client:serviceUrl:defaultZone: http://localhost:8761/eureka/

上述配置代码指定了工程的端口号为 8769,服务名为 service-turbine。turbine.aggregator.app-config 配置了需要监控的服务名,如本例中的 eureka-ribbon-client 和 eureka-feign-client。clusterNameExpression 默认为服务名的集群,此时用默认的即可。turbine.aggregator.cluster-config 可以不写,因为默认就是 default。最后制定了服务注册中心的地址为 http://localhost:8761/eureka/

启动工程 eureka-server、eureka-client、eureka-ribbon-client、eureka-feign-client 和 eureka-monitor-client。在浏览器上访问 http://localhost:8764/hi?name=sisyphus 和 http:localhost:8765/hi?name=sisyphus

在浏览器上打开网址 http://localhost:8765/hystrix,输入监控流的 Url 地址 http://localhost:8769/turbine.stream、监控时间间隔 2000 毫秒和自定义标题

从图中可以看到,这个页面聚合了 eureka-ribbon-client 和 eureka-feign-client 的 Hystrix Dashboard 数据

《深入理解 Spring Cloud 与微服务构建》第九章 熔断器 Hystrix相关推荐

  1. 《深入理解Spring Cloud与微服务构建》出版啦!

    作者简介 方志朋,毕业于武汉理工大学,CSDN博客专家,专注于微服务.大数据等领域,乐于分享,爱好开源,活跃于各大开源社区.著有<史上最简单的Spring Cloud教程>,累计访问量超过 ...

  2. 《深入理解 Spring Cloud 与微服务构建》第十八章 使用 Spring Security OAuth2 和 JWT 保护微服务系统

    <深入理解 Spring Cloud 与微服务构建>第十八章 使用 Spring Security OAuth2 和 JWT 保护微服务系统 文章目录 <深入理解 Spring Cl ...

  3. 《深入理解 Spring Cloud 与微服务构建》第十七章 使用 Spring Cloud OAuth2 保护微服务系统

    <深入理解 Spring Cloud 与微服务构建>第十七章 使用 Spring Cloud OAuth2 保护微服务系统 文章目录 <深入理解 Spring Cloud 与微服务构 ...

  4. 《深入理解 Spring Cloud 与微服务构建》第十六章 Spring Boot Security 详解

    <深入理解 Spring Cloud 与微服务构建>第十六章 Spring Boot Security 详解 文章目录 <深入理解 Spring Cloud 与微服务构建>第十 ...

  5. 《深入理解 Spring Cloud 与微服务构建》第十五章 微服务监控 Spring Boot Admin

    <深入理解 Spring Cloud 与微服务构建>第十五章 微服务监控 Spring Boot Admin 文章目录 <深入理解 Spring Cloud 与微服务构建>第十 ...

  6. 《深入理解 Spring Cloud 与微服务构建》第十四章 服务链路追踪 Spring Cloud Sleuth

    <深入理解 Spring Cloud 与微服务构建>第十四章 服务链路追踪 Spring Cloud Sleuth 文章目录 <深入理解 Spring Cloud 与微服务构建> ...

  7. 《深入理解 Spring Cloud 与微服务构建》第十三章 配置中心 Spring Cloud Config

    <深入理解 Spring Cloud 与微服务构建>第十三章 配置中心 Spring Cloud Config 文章目录 <深入理解 Spring Cloud 与微服务构建>第 ...

  8. 《深入理解 Spring Cloud 与微服务构建》第十二章 服务注册和发现 Consul

    <深入理解 Spring Cloud 与微服务构建>第十二章 服务注册和发现 Consul 文章目录 <深入理解 Spring Cloud 与微服务构建>第十二章 服务注册和发 ...

  9. 《深入理解 Spring Cloud 与微服务构建》第十一章 服务网关

    <深入理解 Spring Cloud 与微服务构建>第十一章 服务网关 文章目录 <深入理解 Spring Cloud 与微服务构建>第十一章 服务网关 一.服务网关简介 二. ...

  10. 《深入理解 Spring Cloud 与微服务构建》第十章 路由网关 Spring Cloud Zuul

    <深入理解 Spring Cloud 与微服务构建>第十章 路由网关 Spring Cloud Zuul 文章目录 <深入理解 Spring Cloud 与微服务构建>第十章 ...

最新文章

  1. vsftp锁定用户在家目录
  2. NServiceBus的安装与调试
  3. Mysql系列七:分库分表技术难题之分布式全局唯一id解决方案
  4. mac电脑安装python_【mac电脑怎么安装python】mac版python安装教程
  5. 如何在SAP云平台ABAP编程环境里创建自己的Z表
  6. android解析XML总结(SAX、Pull、Dom三种方式)
  7. destoon入门实例与常见问题汇总
  8. 服务器协议热更_汽车和电话的开放协议,以及更多开放源新闻
  9. matlab怎么实现OFDM仿真,OFDMmatlab实现仿真源代码
  10. static_cast, dynamic_cast, const_cast,reinterpret_cast探讨
  11. (四)语音识别测试案例
  12. C# 类2010-11-07
  13. linux端更新pip
  14. 便签pc android同步,Windows/iPhone/Android多端同步便签软件
  15. 2017开发者技术和薪酬调查报告
  16. 高铁盈利地图:东部赚翻 中西部普遍巨亏
  17. 科比都这么努力,你还有什么借口不努力呢?
  18. 推箱子游戏的90个经典关卡
  19. 计算机硬盘没内存怎么办,怎么处理闲置旧电脑,内存硬盘都是宝,卖了才可惜!...
  20. 多生产者单消费者捆绑消费问题

热门文章

  1. python 识别登陆验证码图片(完整代码)_python 识别登录验证码图片功能的实现代码(完整代码)...
  2. pytorch 中的数据类型,tensor的创建
  3. [APIO2013]机器人[搜索、斯坦纳树]
  4. 算法笔记_231:网格中移动字母(Java)
  5. 跑了10千米,再一次伤了膝盖
  6. ffmpeg结构体SpecifierOpt说明文档
  7. java并发容器(Map、List、BlockingQueue)
  8. ASP.NET实现多域名多网站共享Session值
  9. 解题报告 Toy Bricks
  10. 编程珠玑---第二章 啊哈!算法