在以前的文章中,我们介绍过使用Gauva实现限流的功能,现在我们来了解一下如何在服务框架中实现熔断和降级的方法。

简介Hystrix

大型系统架构的演进基本上都是这样一个方向:从单体应用到分布式架构。这个演进过程离不开一个字“拆”,我们会把一个系统拆成很多子系统,子系统之间一定会存在依赖,有的是强依赖(比如Http调用),有的是弱依赖(比如,使用消息中间件)。“拆”的主要意义之一就是一个子系统挂了不影响其他的服务正常运行,而对于那么我们拆出来强依赖的服务如果挂了,还是会影响整个系统,所以我们光“拆”是没有达到效果的。

Hystrix源于Netflix,该库可以对那些在访问远程系统、服务、第三方库或者其他方法调用时所产生的延迟或者故障提供更强大的容错能力。说白了就是提供了一种简洁、灵活和强大的框架去处理依赖异常,一个服务挂了不影响其他的服务正常运行,也是微服务概念中熔断,降级的具体框架实现。

它主要的功能如下:

1.对第三方组件进行访问(特别是网络访问)时出现的延迟或者的异常进行保护和控制。

2.在复杂的分布式系统中,停止级联故障。

3.快速失败,快速恢复。

4.可以优雅的降级。

5.可以提供近实时的监控、告警和操作控制。

典型场景:雪崩效应

Hystrix典型的场景就是处理复杂的分布式调用过程中依赖服务延迟或者异常的场景。下图是一张服务依赖图,用户的请求依赖于跨网络的A、H、I、P四个其他的服务。

如果各个服务运行的都很好,那么不会有问题。在大型系统中,随着服务越来越多,网络或者性能问题引起的超时,逻辑的异常带来的不可访问,都是必然会出现的情况。

如上图,一个用户请求的时候,其中的一个依赖服务I出现了延迟,那么整个的这个用户请求将被阻塞。

随着大量流量的增加,一个单一的后端依赖会成为潜在风险,可能导致整个环境的软硬件资源出现问题。不单单这个服务会挂掉,这些问题还有可能,影响环境中的消息队列、线程等其他资源,从而导致系统上的级联故障。最终出现下图的情况。

网络连接失败或降级,服务和服务器失败或变慢,新的库或服务部署改变行为或性能特征,客户端库有bug等等,所有这些都有可能会造成上述的情况,这就需要我们要隔离和管理这些故障和延迟,以便一个失败的依赖项不能影响整个应用程序或系统。而Hystrix正是解决这类问题的。

Hystrix怎样解决这些问题

1.Hystrix使用命令模式HystrixCommand(Command)包装依赖调用逻辑,每个命令在单独线程中/信号授权下执行。

2.可配置依赖调用超时时间,超时时间一般设为比99.5%平均时间略高即可.当调用超时时,直接返回或执行fallback逻辑。

3.为每个依赖提供一个小的线程池(或信号),如果线程池已满调用将被立即拒绝,默认不采用排队.加速失败判定时间。

4.依赖调用结果分:成功,失败(抛出异常),超时,线程拒绝,短路。 请求失败(异常,拒绝,超时,短路)时执行fallback(降级)逻辑。

5.提供熔断器组件,可以自动运行或手动调用,停止当前依赖一段时间(10秒),熔断器默认错误率阈值为50%,超过将自动运行。

6.提供近实时依赖的统计和监控

Hystrix把每个潜在的依赖性进行包装,把每一个依赖项都与另一个依赖项隔离开来,当潜在的问题发生时能限制它的资源,并在调用发生异常时能够决定如何应答给调用方,从而快速的恢复处理,不影响下面的调用。如下图,Hystrix对依赖I配置了5个线程。当调用依赖I的时候,Hystrix配置了两种策略,异常和超时,那么只要有一样触发,或者线程被占满,就可以马上进入我们预设的异常处理逻辑。

示例程序HelloWorld

下面我们用一个简单的例子来展示怎样使用Hystrix来处理上面的场景。一个接口调用超过5秒钟或者出现异常的时候,走另外的降级逻辑。

1.pom文件,引用jar包

<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.12</version>
</dependency>

2.使用Hystrix的命令基类HystrixCommand封装调用逻辑,在执行方法体中,我模拟了3种调用结果:分别是正常调用、调用超时(5s)、和接口中出现异常。

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandProperties; import java.util.concurrent.TimeUnit; /**
* 使用HystrixCommand封装执行方法。继承Hystrix命令基类,泛型参数即调用方法的返回参数
*/
public class HelloWorldCommand extends HystrixCommand<String>
{
private final String name; /**
* 定义构造函数,参数即被包装方法的输入参数
* @param name
*/
public HelloWorldCommand(String name)
{
//定义命令组 和 方法调用超时时间
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("HelloWorldGroup"))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(5000)));
this.name = name;
} /**
* 封装业务逻辑的方法体,在这里执行真正的业务逻辑。
* @return
* @throws Exception
*/
@Override
protected String run() throws Exception
{
//例子中,模拟执行超时
if (name.equals("TimeoutCommand"))
{
TimeUnit.SECONDS.sleep(6);
}
//例子中,模拟出现异常
if (name.equals("ExceptionCommand"))
{
throw new Exception("ExceptionCommand");
}
//例子中,模拟正常返回
return "Hello " + name + "!";
} /**
* 降级方法定义,即,run方法中出现异常后应该执行的方法。包括例子中的超时。
* @return
*/
@Override
protected String getFallback()
{
return "Command failed!";
}
}

3.调用方法

public class HelloWorld
{
public static void main(String[] args)
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String s = new HelloWorldCommand("Nick").execute();
System.out.println(sdf.format(new Date()) + "->" + s); s = new HelloWorldCommand("TimeoutCommand").execute();
System.out.println(sdf.format(new Date()) + "->" + s); s = new HelloWorldCommand("ExceptionCommand").execute();
System.out.println(sdf.format(new Date()) + "->" + s);
}
}

调用方法模拟了3中不同的结果:正常调用、调用超时(5s)、和接口中出现异常。结果如下:

2017-12-24 17:58:18->Hello Nick!
2017-12-24 17:58:23->Command failed!
2017-12-24 17:58:23->Command failed!

Hystrix入门与分析(一):初识Hystrix的更多相关文章

  1. Hystrix入门与分析(二):依赖隔离之线程池隔离

    1.依赖隔离概述 依赖隔离是Hystrix的核心目的.依赖隔离其实就是资源隔离,把对依赖使用的资源隔离起来,统一控制和调度.那为什么需要把资源隔离起来呢?主要有以下几点: 1.合理分配资源,把给资源分 ...

  2. Hystrix入门教程

    Hystrix入门教程 一·什么是Hystrix?Hystrix有什么作用?使用Hystrix有哪些适用场景 Hystrix是springCloud的组件之一,Hystrix 可以让我们在分布式系统中 ...

  3. Hystrix 使用与分析

    转载请注明出处哈:http://hot66hot.iteye.com/admin/blogs/2155036 一:为什么需要Hystrix? 在大中型分布式系统中,通常系统很多依赖(HTTP,hess ...

  4. Spring Cloud实战之初级入门(四)— 利用Hystrix实现服务熔断与服务监控

    目录 1.环境介绍 2.服务监控 2.1 加入依赖 2.2 修改配置文件 2.3 修改启动文件 2.4 监控服务 2.5 小结 3. 利用hystrix实现消费服务熔断 3.1 加入服务熔断 3.2 ...

  5. 断路器之一:Hystrix 使用与分析

    一:为什么需要Hystrix? 在大中型分布式系统中,通常系统很多依赖(HTTP,hession,Netty,Dubbo等),如下图: 在高并发访问下,这些依赖的稳定性与否对系统的影响非常大,但是依赖 ...

  6. [转] Hystrix 使用与分析

    原文地址:http://hot66hot.iteye.com/blog/2155036 转载请注明出处哈:http://hot66hot.iteye.com/blog/2155036 一:为什么需要H ...

  7. Hystrix入门指南

    Introduction 1.Where does the name come from? hystrix对应的中文名字是“豪猪”,豪猪周身长满了刺,能保护自己不受天敌的伤害,代表了一种防御机制,这与 ...

  8. SQLite入门与分析(二)---设计与概念(续)

    SQLite入门与分析(二)---设计与概念(续)   写在前面:本节讨论事务,事务是DBMS最核心的技术之一.在计算机科学史上,有三位科学家因在数据库领域的成就而获ACM图灵奖,而其中之一Jim G ...

  9. ArcGIS for Desktop入门教程_第四章_入门案例分析 - ArcGIS知乎-新一代ArcGIS问答社区

    原文:ArcGIS for Desktop入门教程_第四章_入门案例分析 - ArcGIS知乎-新一代ArcGIS问答社区 1 入门案例分析 在第一章里,我们已经对ArcGIS系列软件的体系结构有了一 ...

随机推荐

  1. C#_02.15_基础六_.NET类

    C#_02.15_基础六_.NET类 一.类继承是一个类在另一个类的基础上进行的扩展. 继承的子类拥有父类的全部成员.索引子类拥有本身的全部成员以及父类的全部成员. 可以对基类成员进行隐藏,如果必须的 ...

  2. Windows下NetBeans中文乱码解决办法

    找到你的Netbeans安装目录下的etc文件夹,用记事本打开netbeans.conf,找到netbeans_default_options(不是最后那个带句号的…), 在其属性的最后(冒号以内)加 ...

  3. 01、Spar内核架构原理

        附件列表

  4. Grafana数据可视化

    1.1 Grafana简介 1.1.1 Grafana是什么? 一个类似Kibana的东西,也是对后端的数据进行实时展示,那么Grafana和Kibana有什么区别?在我看来区别不大,不过在大家的日常 ...

  5. windows ip 缓存清理

    ip缓存 ipconfig /release dns缓存 ipconfig/flushdns

  6. CSS单行格式化与压缩

    工具简介:CSS单行格式化与压缩工具

  7. uc浏览器视频缓存合并工具

    1.该软件用于将uc浏览器中零散的视频缓存切片处理成完整的视频文件. 开发语言:C#开发工具: Visual Studio 2017 Community 实例图示: 程序代码下载地址 windows ...

  8. 使用Git Subtree在多个项目中共用同一个子项目

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/8427796.html 场景一:已有一个大项目,需要把其中一部分内容独立出来作为共用子项目,被其他项目引用 一: ...

  9. Linux 搭建git 自己拉取本地 git pull,其他地方的git仓库拉取代码

    Linux 下建立 Git 与 GitHub 的连接 Git 是一款开源的分布式版本控制系统,而 GitHub 是依托 Git 的代码托管平台. GitHub 利用 Git 极其强大的克隆和分支功能, ...

  10. 自然语言处理中的N-Gram模型

    N-Gram(有时也称为N元模型)是自然语言处理中一个非常重要的概念,通常在NLP中,人们基于一定的语料库,可以利用N-Gram来预计或者评估一个句子是否合理.另外一方面,N-Gram的另外一个作用是 ...