一文彻底搞定Hystrix!
前言
Netflix Hystrix断路器是什么?
Netflix Hystrix是SOA/微服务架构中提供服务隔离、熔断、降级机制的工具/框架。Netflix Hystrix是断路器的一种实现,用于高微服务架构的可用性,是防止服务出现雪崩的利器。
为什么需要断路器
在分布式架构中,一个应用依赖多个服务是非常常见的,如果其中一个依赖由于延迟过高发生阻塞,调用该依赖服务的线程就会阻塞,如果相关业务的QPS较高,就可能产生大量阻塞,从而导致该应用/服务由于服务器资源被耗尽而拖垮。
另外,故障也会在应用之间传递,如果故障服务的上游依赖较多,可能会引起服务的雪崩效应。就跟数据瘫痪,会引起依赖该数据库的应用瘫痪是一样的道理。
当一个应用依赖多个外部服务,一切都正常的情况下,如下图:
如果其中一个依赖发生延迟,当前请求就会被阻塞
出现这种情况后,如果没有应对措施,后续的请求也会被持续阻塞
每个请求都占用了系统的CPU、内存、网络等资源,如果该应用的QPS较高,那么该应用所以的服务资源会被快速消耗完毕,直至应用死掉。如果这个出问题的依赖(Dependency I),不止这一个应用,亦或是受影响的应用上层也有更多的依赖,那就会带来我们前面所提到的服务雪崩效应。 所以,为了应对以上问题,就需要有支持服务隔离、熔断等操作的工具。
Hystrix 简介
Hystrix具备哪些能力/优点?
在通过网络依赖服务出现高延迟或者失败时,为系统提供保护和控制 可以进行快速失败,缩短延迟等待时间和快速恢复:当异常的依赖回复正常后,失败的请求所占用的线程会被快速清理,不需要额外等待 提供失败回退(Fallback)和相对优雅的服务降级机制 提供有效的服务容错监控、报警和运维控制手段
Hystrix 如何解决级联故障/防止服务雪崩?
Hystrix将请求的逻辑进行封装,相关逻辑会在独立的线程中执行
Hystrix有自动超时策略,如果外部请求超过阈值,Hystrix会以超时来处理
Hystrix会为每个依赖维护一个线程池,当线程满载,不会进行线程排队,会直接终止操作
- Hystrix有熔断机制:在依赖服务失效比例超过阈值时,手动或者自动地切断服务一段时间 所以,当引入了Hystrix之后,当出现某个依赖高延迟的时候
Hystrix 工作原理
Hystrix工作流
- 创建HystrixCommand 或者 HystrixObservableCommand 对象
- 执行命令execute()、queue()、observe()、toObservable()
- 如果请求结果缓存这个特性被启用,并且缓存命中,则缓存的回应会立即通过一个Observable对象的形式返回
- 检查熔断器状态,确定请求线路是否是开路,如果请求线路是开路,Hystrix将不会执行这个命令,而是直接执行getFallback
- 如果和当前需要执行的命令相关联的线程池和请求队列,Hystrix将不会执行这个命令,而是直接执行getFallback
- 执行HystrixCommand.run()或HystrixObservableCommand.construct(),如果这两个方法执行超时或者执行失败,则执行getFallback()
- Hystrix 会将请求成功,失败,被拒绝或超时信息报告给熔断器,熔断器维护一些用于统计数据用的计数器。这些计数器产生的统计数据使得熔断器在特定的时刻,能短路某个依赖服务的后续请求,直到恢复期结束,若恢复期结束根据统计数据熔断器判定线路仍然未恢复健康,熔断器会再次关闭线路。
- 依赖隔离Hystrix采用舱壁隔离模式隔离相互之间的依赖关系,并限制对其中任何一个的并发访问。
可能会有人有疑问,为什么不依赖于HTTP Client去做容错保护(快速失败、熔断等),而是在访问依赖之外通过线程&线程池隔离的方式做这个断路器(Hystrix)`
主要是以下几个方面:
- 不同的依赖执行的频率不同,需要分开来对待
- 不同的依赖可能需要不同的Client的工具/协议来访问,比如我们可能用HTTP Client,可能用Thrift Client。
- Client在执行的过程中也可能会出现非网络异常,这些都应该被隔离
- Client的变化会引起断路器的变化
SpringCloud:Ribbon + Hystrix应用
- 项目中引入Hystrix
修改pom.xml,引入Spring Cloud Netflix Hystrix
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- 配置Hystrix启动类
修改启动类Application.java,增加@EnableHystrix注解开启Hystrix
@EnableHystrix
@EnableDiscoveryClient
@SpringBootApplication
public class Application { public static void main(String[] args) {
SpringApplication.run(Application.class, args);
} @Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
- 断路处理实现
修改TestService.java,增加断路器功能
- 在index方法上增加注解 @HystrixCommand并通过fallbackMethod参数指定断路后执行的方法
- 定义断路处理方法,返回服务/操作断路后的提示
@Service
public class TestService { @Autowired
private RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "indexError")
public Object index() {
return restTemplate.getForObject("http://testservice", String.class);
} public Object plus(int numA, int numB) {
String url = String.format("http://testservice/plus?numA=%s&numB=%s", numA, numB);
return restTemplate.getForObject(url, String.class);
} public Object indexError() {
return "{\"code\": 999,\"message\": \"服务断路\"}";
}
}
- 断路处理测试
启动 Application 项目, 访问:http://localhost:8604/ti ,将看到
{
"code": 0,
"message": "hello",
"content": null,
"serviceName": "testservice",
"host": "localhost:8602"
}
关闭testservice,然后再访问 http://localhost:8604/ti ,将看到
{
"code": 999,
"message": "服务断路"
}
至此完成Ribbon+Hystrix的熔断。
SpringCloud:Feign + Hystrix应用
- 开启Hystrix 修改application.yml,开启Hystrix
feign:
hystrix:
enabled: true
- 断路处理实现
新建 TestServiceHystrix.java作为TestService的断路处理实现
@Component
public class TestServiceHystrix implements TestService { @Override
public String indexService() {
return "{\"code\": 999,\"message\": \"服务断路\"}";
} @Override
public Result plusService(int numA, int numB) {
Result result = new Result();
result.setCode(999);
result.setMessage("服务断路");
return new Result();
} @Override
public Result plusabService(Plus plus) {
Result result = new Result();
result.setCode(999);
result.setMessage("服务断路");
return new Result();
} @Override
public Result plus2Service(Plus plus) {
Result result = new Result();
result.setCode(999);
result.setMessage("服务断路");
return new Result();
}
}
- 修改TestService,指定fallback类
@FeignClient(value = "testservice", fallback = TestServiceHystrix.class)
public interface TestService { @RequestMapping(value = "/", method = RequestMethod.GET)
String indexService(); @RequestMapping(value = "/plus", method = RequestMethod.GET)
Result plusService(@RequestParam(name = "numA") int numA, @RequestParam(name = "numB") int numB); @RequestMapping(value = "/plus", method = RequestMethod.POST, consumes = "application/json")
Result plusabService(Plus plus); @RequestMapping(value = "/plus2", method = RequestMethod.POST)
Result plus2Service(@RequestBody Plus plus); }
- 启动 feign Application 项目
- 访问:http://localhost:8605/ti ,将看到
{
"code": 0,
"message": "hello",
"content": null,
"serviceName": "testservice",
"host": "localhost:8602"
}
- 关闭testservice,然后再访问 http://localhost:8605/ti ,将看到
{
"code": 999,
"message": "服务断路"
}
至此完成Feign+Hystrix的熔断。
结束
欢迎关注公众号! 公众号回复:
入群
,扫码加入我们交流群!
一文彻底搞定Hystrix!的更多相关文章
- 来吧!一文彻底搞定Vue组件!
作者 | Jeskson 来源 | 达达前端小酒馆 Vue组件的概述 组件是什么呢,了解组件对象的分析,Vue组件中的data属性,props传递数据的原理到底是什么. 事件通信的那些事 如何了解父子 ...
- 用ORM的思想操作XML文档,一个对象就搞定不要太简单。滚蛋吧!XmlDocument、XmlNode、Xml***……
大家有没有这样的感受,一涉及XML文档操作就得百度一遍.是不是非!常!烦!.各种类型,各种方法,更别提为了找到一个节点多费劲.本来想写个XML操作的工具方法,写了两行一想既然XML文档是有规律的,如果 ...
- 一文搞定 SonarQube 接入 C#(.NET) 代码质量分析
1. 前言 C#语言接入Sonar代码静态扫描相较于Java.Python来说,相对麻烦一些.Sonar检测C#代码时需要预先编译,而且C#代码必须用MSbuid进行编译,如果需要使用SonarQub ...
- 【项目实践】一文带你搞定Spring Security + JWT
以项目驱动学习,以实践检验真知 前言 关于认证和授权,R之前已经写了两篇文章: [项目实践]在用安全框架前,我想先让你手撸一个登陆认证 [项目实践]一文带你搞定页面权限.按钮权限以及数据权限 在这两篇 ...
- 一文搞定MySQL的事务和隔离级别
一.事务简介 事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成. 一个数据库事务通常包含了一个序列的对数据库的读/写操作.它的存在包含有以下两个目的: 为数据库操作序列提供 ...
- 一文搞定scrapy爬取众多知名技术博客文章保存到本地数据库,包含:cnblog、csdn、51cto、itpub、jobbole、oschina等
本文旨在通过爬取一系列博客网站技术文章的实践,介绍一下scrapy这个python语言中强大的整站爬虫框架的使用.各位童鞋可不要用来干坏事哦,这些技术博客平台也是为了让我们大家更方便的交流.学习.提高 ...
- 【RabbitMQ】一文带你搞定RabbitMQ延迟队列
本文口味:鱼香肉丝 预计阅读:10分钟 一.说明 在上一篇中,介绍了RabbitMQ中的死信队列是什么,何时使用以及如何使用RabbitMQ的死信队列.相信通过上一篇的学习,对于死信队列已经有了更 ...
- 一文搞定Spring Boot + Vue 项目在Linux Mysql环境的部署(强烈建议收藏)
本文介绍Spring Boot.Vue .Vue Element编写的项目,在Linux下的部署,系统采用Mysql数据库.按照本文进行项目部署,不迷路. 1. 前言 典型的软件开发,经过" ...
- 【项目实践】一文带你搞定Session和JWT的登录认证方式
以项目驱动学习,以实践检验真知 前言 登录认证,估计是所有系统中最常见的功能了,并且也是最基础.最重要的功能.为了做好这一块而诞生了许多安全框架,比如最常见的Shiro.Spring Security ...
随机推荐
- 双十一NGK官方快讯!
- K8S部署Redis Cluster集群(三主三从模式) - 部署笔记
一.Redis 介绍 Redis代表REmote DIctionary Server是一种开源的内存中数据存储,通常用作数据库,缓存或消息代理.它可以存储和操作高级数据类型,例如列表,地图,集合和排序 ...
- [转]ROS Q&A | How to read LaserScan data
http://www.theconstructsim.com/read-laserscan-data/ Step 1. Open a project on ROS Development Studio ...
- nginx日志文件切分
定义cut_nginx_log.sh 日志文件脚本如下 #!/bin/bash#LOGS_PATH为日志存放路径LOGS_PATH=/weblog/nginx/logsYESTERDAY=$(date ...
- CVer想知道的都在这里了,一起分析下《中国计算机视觉人才调研报告》吧!
最近闲来无事,老潘以一名普通算法工程师的角度,结合自身以及周围人的情况,理性也感性地分析一下极市平台前些天发布的2020年度中国计算机视觉人才调研报告. 以下的"计算机视觉人才"简 ...
- 微信小程序:日期组件picker的使用
1.页面代码 <view class="right"> <picker mode="date" value="{{material. ...
- TorchVision 预训练模型进行推断
torchvision.models 里包含了许多模型,用于解决不同的视觉任务:图像分类.语义分割.物体检测.实例分割.人体关键点检测和视频分类. 本文将介绍 torchvision 中模型的入门使用 ...
- DRF 三大认证的配置及使用方法
目录 三大认证 一.身份认证 1.身份认证配置 1.1 全局配置身份认证模块 1.2 局部配置身份认证模块 2.drf提供的身份认证类(了解) 3.rf-jwt提供的身份认证类(常用) 4.自定义身份 ...
- Docker Hub 镜像加速器
一.概述 国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器.Docker 官方和国内很多云服务商都提供了国内加速器服务. 二.配置加速地址 Ubuntu 16.04+.De ...
- 六. SpringCloud网关
1. Gateway概述 1.1 Gateway是什么 服务网关还可以用Zuul网关,但是Zuul网关由于一些维护问题,所以这里我们学习Gateway网关,SpringCloud全家桶里有个很重要的组 ...