Hystrix 断路器作用
     2019-03-02 17:03:28   深圳市 阅读数 38 点赞 收藏 举报 编辑

网络上的大部分hystrix文章,都是教你怎么用、如何搭建起来,却没有太好的文章能介绍Hystrix到底是什么?它为什么这么流行?在什么场景下用?解决什么痛点?

关于Hystrix的介绍,一般是这样的:

Hystrix 供分布式系统使用,提供延迟和容错功能,隔离远程系统、访问和第三方程序库的访问点,防止级联失败,保证复杂的分布系统在面临不可避免的失败时,仍能有其弹性

这样的解释未免太过于抽象和难以理解,

一般来说,微服务的架构是这样的

图片.png

图中我们可以看到服务A和B都依赖于服务C,

在高爆发的情况下,服务A连续请求C,如果没有采用适当的缓存,这个的时候,C往往会不堪重负,出现异常情况。

比如说:

  1. 查看文章详情接口,可能是根据文章的主键进行查询,效率非常高。
  2. 某个文章统计接口,根据复杂的SQ语句查询数据库才会得到的结果,效率很第,同时占用数据库内存和CPU

如果当“某个文章统计接口”被大量访问,数据库出现异常情况,有新的请求的时候,总会返回数据库连接超时,同时也包括“查看文章详情页面”。此时,对于访问文章详情的用户来说可能会出现500错误。

也就是说,“查看文章详情接口”和“某个文章统计接口”两个不同的接口(或者说两个不同的逻辑)会相互影响

如何解决此类的问题呢?

这就涉及到我们这篇文章要讲到的Hystrix,Hystrix能够对“查看文章详情接口”和“某个文章统计接口”这两个不同的页面进行隔离,当任何一个出现问题的时候,不会影响到其他的页面。

也就说当“某个文章统计接口”被大量访问,出现了数据库异常情况,导致web应用出现500,那么Hystrix要极力去保证“查看文章详情接口”是正常的。

如何做到呢?

Hystrix提供了两种解决方案:

  1. 线程池。
  2. 信号量。

在访问微服务的时候,Hystrix会把不同的逻辑放到不同的线程池里去,同时会启用一个“线程池管理员”来查看线程池里所有线程的执行情况,如果某个连接池异常出现达到一定的量,那么此时,所有的请求都不会再请求到服务C,直接被Hystrix拦截,并会调用一个本地方法来处理“异常达到一定量”的这种情况,这个过程也叫“降级”。

在上述的业务描述中,“某个文章统计接口”和“查看文章详情接口”是两个不同的逻辑,会被Hystrix放到两个不同的线程池里,当“某个文章统计接口”的错误率(异常情况)达到一定的量(这个量可以配置),Hystrix立即切断了“某个文章统计接口”和服务C之间的连接,保证“某个文章统计接口”不会再继续消耗服务C的资源。而“查看文章详情接口”的错误率极低或者系统延迟极低,Hystrix对其正常放行。从而达到了隔离的作用。

Hystrix用得更多的是在RPC(Remote Procedure Call)的使用场景,在分布式架构下,不同的系统之间会相互调用,一旦某个子系统出现异常,Hystrix立即切断其他系统和异常子系统的联系。

如下图所示:

h5.png

假设上图的顶部“User Request”是访问某在线商城的个人中心页面,个人中心页面里显示了:个人资料、推荐商品、购物车和我的快递信息等。

个人资料、推荐商品、购物车、我的快递信息分别来至于四个子系统。大概由如下代码组成:

public void userCenter(){

        List<Goods> recommendGoodsList = system1.queryGoodsList();
        List<Goods> myGoodsList = system2.queryMyGoodsList();
        List<ExpressInfo> myExpressInfoList = system3.queyrMyExpressList();
        User myInfo = system4.queryMyInfo();
  
        request.setAttribute(“recommendGoodsList”,recommendGoodsList);
        request.setAttribute(“myGoodsList”,myGoodsList);
        request.setAttribute(“myExpressInfoList”,myExpressInfoList);
        request.setAttribute(“myInfo”,myInfo);

        render(“userCenter.html”);
}

此时,若“快递信息”子系统出现了问题,如下图所示: 

h4.png

  1. public void userCenter(){
  2.         List<Goods> recommendGoodsList = system1.queryGoodsList();
  3.         List<Goods> myGoodsList = system2.queryMyGoodsList();
  4.         List<ExpressInfo> myExpressInfoList = system3.queyrMyExpressList();
  5.         User myInfo = system4.queryMyInfo();
  6.    
  7.         request.setAttribute(“recommendGoodsList”,recommendGoodsList);
  8.         request.setAttribute(“myGoodsList”,myGoodsList);
  9.         request.setAttribute(“myExpressInfoList”,myExpressInfoList);
  10.         request.setAttribute(“myInfo”,myInfo);
  11.         render(“userCenter.html”);
  12. }

那么此时,第四行代码“ system3.queyrMyExpressList();”会出现等待情况,从而导致所有的请求都会出现等待情况,如下图:

h3.png

更加可怕的是,当所有的请求都在等待的时候,系统资源会很快被耗尽,从而导致系统奔溃,甚至连重启系统都不行(因为重启后,请求又立即进来消耗资源)。一个服务器的等待,也可能会导致其他服务器出现等待(不同的服务器之间往往都会有相互调用数据的情况),此时所有的业务系统全部奔溃,又称:雪崩效应。

当有了Hystrix的隔离之后,每个业务都会在自己的线程池里被管理,当List<ExpressInfo> myExpressInfoList = system3.queyrMyExpressList(); 出现问题(延迟或错误)达到一定量的时候,system3.queyrMyExpressList();会立即返回数据(一般情况下是空数据,由降级函数执行返回结果)而不会出现等待的情况,从而保证系统正常运作。

我们回头来看下Hystrix的定义:

“Hystrix 供分布式系统使用,提供延迟和容错功能,隔离远程系统、访问和第三方程序库的访问点,防止级联失败,保证复杂的分布系统在面临不可避免的失败时,仍能有其弹性。”

此时,你是否对Hystrix的定义有所理解了呢?

值得赞赏的是,Hystrix对线程池的管理,还提供了一个可视化的监控系统 hystrix-dashboard 来查看每个线程池的情况。如果你的电脑上安装有docker,可以通过以下命令来启动 hystrix-dashboard

docker run --rm -ti -p 7979:7979 kennedyoliveira/hystrix-dashboard

如果没有docker环境也没关系,你也可以执行通过以下方法来编译启动 hystrix-dashboard

  1. $ git clone https://github.com/Netflix/Hystrix.git
  2. $ cd Hystrix/hystrix-dashboard
  3. $ ../gradlew appRun
  4. > Building > :hystrix-dashboard:appRun > Running at http://localhost:7979/hystrix-dashboard

启动 hystrix-dashboard 成功后,可以通过浏览器访问http://localhost:7979/hystrix-dashboard 来查看 hystrix-dashboard 。

如下图所示:

h2.png

填写“web应用”的Hystrix的stream地址后,点击“monitor stream”按钮,我们就可以看到Hystrix对整个应用的监控情况了。

h1.png

 

备注:在Jboot框架开发的应用中,我们需要在jboot.properties配置“jboot.hystrix.url = /hystrix.stream”,此时Hystrix的stream地址为:http://host:port/hystrix.stream

Srping Cloud等要做的事情比较多,不像Jboot一行配置就可以使用,请自行查看其帮助文档。

到此,Hystrix的介绍就完毕了,这篇文章并没有涉及到Hystrix如何去使用,网上有非常多的文章来讲解如何使用Hystrix,但是却没有一篇文章来系统介绍什么是Hystrix。我觉得对任何技术,理解要比使用重要很多,这也是我为什么写这篇文章的原因。

 

通过这篇文章:

  • 你能对Hystrix有一个较好的理解了吗?
  • 你是否继续希望我编写关于Hystrix更加高级的文章?

欢迎给我留言。


 原文地址:https://my.oschina.net/yangfuhai/blog/1628224

 

发表评论