前言?

  1. Netflix Hystrix断路器是什么?

Netflix Hystrix是SOA/微服务架构中提供服务隔离、熔断、降级机制的工具/框架。Netflix Hystrix是断路器的一种实现,用于高微服务架构的可用性,是防止服务出现雪崩的利器。

  1. 为什么需要断路器

在分布式架构中,一个应用依赖多个服务是非常常见的,如果其中一个依赖由于延迟过高发生阻塞,调用该依赖服务的线程就会阻塞,如果相关业务的QPS较高,就可能产生大量阻塞,从而导致该应用/服务由于服务器资源被耗尽而拖垮。

另外,故障也会在应用之间传递,如果故障服务的上游依赖较多,可能会引起服务的雪崩效应。就跟数据瘫痪,会引起依赖该数据库的应用瘫痪是一样的道理。

当一个应用依赖多个外部服务,一切都正常的情况下,如下图:

如果其中一个依赖发生延迟,当前请求就会被阻塞

出现这种情况后,如果没有应对措施,后续的请求也会被持续阻塞

每个请求都占用了系统的CPU、内存、网络等资源,如果该应用的QPS较高,那么该应用所以的服务资源会被快速消耗完毕,直至应用死掉。如果这个出问题的依赖(Dependency I),不止这一个应用,亦或是受影响的应用上层也有更多的依赖,那就会带来我们前面所提到的服务雪崩效应。
所以,为了应对以上问题,就需要有支持服务隔离、熔断等操作的工具。

Hystrix 简介

  1. Hystrix具备哪些能力/优点?

    在通过网络依赖服务出现高延迟或者失败时,为系统提供保护和控制
    可以进行快速失败,缩短延迟等待时间和快速恢复:当异常的依赖回复正常后,失败的请求所占用的线程会被快速清理,不需要额外等待
    提供失败回退(Fallback)和相对优雅的服务降级机制
    提供有效的服务容错监控、报警和运维控制手段

  2. Hystrix 如何解决级联故障/防止服务雪崩?

  • Hystrix将请求的逻辑进行封装,相关逻辑会在独立的线程中执行

  • Hystrix有自动超时策略,如果外部请求超过阈值,Hystrix会以超时来处理

  • Hystrix会为每个依赖维护一个线程池,当线程满载,不会进行线程排队,会直接终止操作

  • Hystrix有熔断机制: 在依赖服务失效比例超过阈值时,手动或者自动地切断服务一段时间
    所以,当引入了Hystrix之后,当出现某个依赖高延迟的时候

Hystrix 工作原理

  1. Hystrix工作流

  1. 创建HystrixCommand 或者 HystrixObservableCommand 对象
  2. 执行命令execute()、queue()、observe()、toObservable()
  3. 如果请求结果缓存这个特性被启用,并且缓存命中,则缓存的回应会立即通过一个Observable对象的形式返回
  4. 检查熔断器状态,确定请求线路是否是开路,如果请求线路是开路,Hystrix将不会执行这个命令,而是直接执行getFallback
  5. 如果和当前需要执行的命令相关联的线程池和请求队列,Hystrix将不会执行这个命令,而是直接执行getFallback
  6. 执行HystrixCommand.run()或HystrixObservableCommand.construct(),如果这两个方法执行超时或者执行失败,则执行getFallback()
  7. Hystrix 会将请求成功,失败,被拒绝或超时信息报告给熔断器,熔断器维护一些用于统计数据用的计数器。这些计数器产生的统计数据使得熔断器在特定的时刻,能短路某个依赖服务的后续请求,直到恢复期结束,若恢复期结束根据统计数据熔断器判定线路仍然未恢复健康,熔断器会再次关闭线路。
  8. 依赖隔离Hystrix采用舱壁隔离模式隔离相互之间的依赖关系,并限制对其中任何一个的并发访问。

可能会有人有疑问,为什么不依赖于HTTP Client去做容错保护(快速失败、熔断等),而是在访问依赖之外通过线程&线程池隔离的方式做这个断路器(Hystrix)`

主要是以下几个方面:

  • 不同的依赖执行的频率不同,需要分开来对待
  • 不同的依赖可能需要不同的Client的工具/协议来访问,比如我们可能用HTTP Client,可能用Thrift Client。
  • Client在执行的过程中也可能会出现非网络异常,这些都应该被隔离
  • Client的变化会引起断路器的变化

SpringCloud:Ribbon + Hystrix应用

  1. 项目中引入Hystrix

修改pom.xml,引入Spring Cloud Netflix Hystrix

  <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
  </dependency>
  1. 配置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();
    }
}
  1. 断路处理实现

修改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\": \"服务断路\"}";
    }
}
  1. 断路处理测试

启动 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应用

  1. 开启Hystrix
    修改application.yml,开启Hystrix
feign:
  hystrix:
    enabled: true
  1. 断路处理实现

新建 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();
    }
}
  1. 修改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);

}
  1. 启动 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!的更多相关文章

  1. 一文带你快速搞懂动态字符串SDS,面试不再懵逼

    目录 redis源码分析系列文章 前言 API使用 embstr和raw的区别 SDSHdr的定义 SDS具体逻辑图 SDS的优势 更快速的获取字符串长度 数据安全,不会截断 SDS关键代码分析 获取 ...

  2. 面试都在问的微服务、服务治理、RPC、下一代微服务框架... 一文带你彻底搞懂!

    文章每周持续更新,「三连」让更多人看到是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) 单体式应用程序 与微服务相对的另一个概念是传统的单体式应用程序( ...

  3. 面试都在问的「微服务」「RPC」「服务治理」「下一代微服务」一文带你彻底搞懂!

    ❝ 文章每周持续更新,各位的「三连」是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) ❞ 单体式应用程序 与微服务相对的另一个概念是传统的「单体式应用程 ...

  4. C语言重点——指针篇(一文让你完全搞懂指针)| 从内存理解指针 | 指针完全解析

    有干货.更有故事,微信搜索[编程指北]关注这个不一样的程序员,等你来撩~ 注:这篇文章好好看完一定会让你掌握好指针的本质 C语言最核心的知识就是指针,所以,这一篇的文章主题是「指针与内存模型」 说到指 ...

  5. C\C++语言重点——指针篇 | 为什么指针被誉为 C 语言灵魂?(一文让你完全搞懂指针)

    本篇文章来自小北学长的公众号,仅做学习使用,部分内容做了适当理解性修改和添加了博主的个人经历. 注:这篇文章好好看完一定会让你掌握好指针的本质! 看到标题有没有想到什么? 是的,这一篇的文章主题是「指 ...

  6. 一文让你彻底搞懂 vue-Router

    路由是网络工程里面的专业术语,就是通过互联把信息从源地址传输到目的地址的活动.本质上就是一种对应关系.分为前端路由和后端路由. 后端路由: URL 的请求地址与服务器上的资源对应,根据不同的请求地址返 ...

  7. .NETCore C# 中级篇2-4 一文带你完全弄懂正则表达式

    .NETCoreCSharp 中级篇2-4 本节内容为正则表达式的使用 简介 有的时候,你是否有过这种需求:判断一个Ip地址.邮箱.密码规则是否合法.如果让你使用if一类的传统方法进行处理,你肯定会被 ...

  8. 8分钟带你深入浅出搞懂Nginx

    Nginx是一款轻量级的Web服务器.反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用. 图基本上说明了当下流行的技术架构,其中Nginx有点入口网关的味道. 反向代 ...

  9. Spirit带你彻底搞懂JS的6种继承方案

    JavaScript中实现继承的6种方案 01-原型链的继承方案 function Person(){ this.name="czx"; } function Student(){ ...

随机推荐

  1. regex read once bug

    regex read once bug read once bug StackOverflow Question https://stackoverflow.com/questions/5916796 ...

  2. Masterboxan INC:OPEC+达成产量协议 产油联盟内部分歧逐步加大

    本周,"OPEC+"在维也纳召开了今年首次部长级会议,并就未来两个月的石油生产计划达成协议.据了解,此次会议的协商过程可谓一波三折,虽然最后沙特意外宣布减产维持了OPEC+大体产量 ...

  3. 交易所频频跑路?Baccarat去中心化交易平台助力资金安全

    过去,黑客攻击可能是交易所跑路的最常见原因.自OKEx事件以来,这些交易所暂停提币或跑路还多了一个原因,就是因创始人正在协助调查. 据不完全统计,自OKEx于10月16日宣布暂停提币后不到两个月,已经 ...

  4. 线段树&数链剖分

    傻逼线段树,傻逼数剖 线段树 定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现 ...

  5. restful风格的理解

    简而言之,就是不同的命令响应不同的操作: 关注点在url中的不同参数,是因为不同的参数才使得不同的method去对应的不同的操作.

  6. 配置mysql数据库时出再错误:LookupError: No installed app with label 'admin'.

    版本: windows10+py37+django2.2 错误: 项目启动时出现,No installed app with label 'admin' 解决办法: 安装最新的 pip install ...

  7. vue:表单验证时,trigger的值什么时候选blur什么时候选change

    对el-input输入框的验证,trigger的值选blur,即失去焦点时进行验证. 下拉框(el-select).日期选择器(el-date-picker).复选框(el-checkbox).单选框 ...

  8. 001 说说Python中的深拷贝和浅拷贝

    在Python编程中忽略深拷贝和浅拷贝可能会造成未知的风险. 比如我们打算保存一份原始对象的副本作为上一状态的记录,此后修改原始对象数据时,若是副本对象的数据也发生改变,那么这就是一个严重的错误. 注 ...

  9. c++ vector对象

    下面随笔讲解c++ vector对象. vector对象 为什么需要vector? 封装任何类型的动态数组,自动创建和删除. 数组下标越界检查. 封装的如ArrayOfPoints也提供了类似功能,但 ...

  10. pytorch(13)卷积层

    卷积层 1. 1d/2d/3d卷积 Dimension of Convolution 卷积运算:卷积核在输入信号(图像)上滑动,相应位置上进行乘加 卷积核:又称为滤波器,过滤器,可认为是某种模式,某种 ...