Hystrix的简单介绍

最近几天我直在探索Netflix Hystrix library,领会到了这个优秀类库提供的特性。

引用Hystrix网站的原话:
   Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, 
services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where 
failure is inevitable.
   Hystrix通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力,阻止故障的连锁反应

,并允许你快速失败并迅速恢复。

这里有很多要分析的关键词,然而体验Hystrix的最佳方式就是亲手做一个例子来试试。

一个不可预测的服务

考虑一个服务,一个携带json结构信息并且返回一个确认的奇怪服务。
{
    "id":"1",
    "payload": "Sample Payload",
    "throw_exception":false,
    "delay_by": 0
}

这个服务有一个payload属性,但是额外多带了两个属性。
delay_by 在延迟到达指定的毫秒数后返回一个确认响应。
throw_exceptions 在指定的延迟后导致异常

下面是响应例子:
{
 "id":"1",
 "received":"Sample Payload",
 "payload":"Reply Message"
}

这里是我的 github地址,可以下载示例代码。在这个例子中我用到了 Netflix Karyon2 ,示例代码处理请求的部分非常简洁。来看看
这个类库用在这是多好用吧:

import com.netflix.governator.annotations.Configuration;
import rx.Observable;
import service1.domain.Message;
import service1.domain.MessageAcknowledgement;


import java.util.concurrent.TimeUnit;


public class MessageHandlerServiceImpl implements MessageHandlerService {


    @Configuration("reply.message")
    private String replyMessage;


    public Observable<MessageAcknowledgement> handleMessage(Message message) {
        logger.info("About to Acknowledge");
        return Observable.timer(message.getDelayBy(), TimeUnit.MILLISECONDS)
                .map(l -> message.isThrowException())
                .map(throwException -> {
                    if (throwException) {
                        throw new RuntimeException("Throwing an exception!");
                    }
                    return new MessageAcknowledgement(message.getId(), message.getPayload(), replyMessage);
                });
    }




}

在这里,我们就有了一个可以响应随意的延迟和失败的候选服务了。

服务的客户端

现在看一下客户端,我们用 Netflix Feign来进行调用,这是另一个很棒的类库,需通过注解方式来使用:
package aggregate.service;


import aggregate.domain.Message;
import aggregate.domain.MessageAcknowledgement;
import feign.RequestLine;


public interface RemoteCallService {
    @RequestLine("POST /message")
    MessageAcknowledgement handleMessage(Message message);
}

在这几行中,它创建了一个代理,其实现了使用配置的接口。

RmoteCallService remoteCallService = Feign.builder()
        .encoder(new JacksonEncoder())
        .decoder(new JacksonDecoder())
        .target(RemoteCallService.class, "http://127.0.0.1:8889");

我有多个针对这个远程客户端的委托调用,所有的都在下面这个url中
http://localhost:8888/noHystrix?message=Hello&delay_by=0&throw_exception=false
下面第一个例子是没有使用Hystrix的例子。

没有使用Hystrix的例子

在第一个例子中,考虑不用Hystrix来调用这个远程服务,如果我尝试以以下方式调用
http://localhost:8888/noHystrix?message=Hello&delay_by=5000&throw_exception=false或 
http://localhost:8888/noHystrix?message=Hello&delay_by=5000&throw_exception=true,
在这两种实例中用户对服务的请求都会在等待5秒后才会收到响应。

有些事情在这里就立即很明显了:

1.如果服务响应缓慢,那么客户对服务的请求就会被强制等待到服务返回。

2.在高负载下,很有可能所有处理用户请求的线程资源被耗竭,而不能响应用户的进一步请求。

3.如果服务抛出异常,客户端不能很好的处理。


Hystrix命令包装远程调用

在上一个例子中,我用50个用户进行了一下压力测试,得到结果如下:

================================================================================
---- Global Information --------------------------------------------------------
> request count                                         50 (OK=50     KO=0     )
> min response time                                   5007 (OK=5007   KO=-     )
> max response time                                  34088 (OK=34088  KO=-     )
> mean response time                                 17797 (OK=17797  KO=-     )
> std deviation                                       8760 (OK=8760   KO=-     )
> response time 50th percentile                      19532 (OK=19532  KO=-     )
> response time 75th percentile                      24386 (OK=24386  KO=-     )
> mean requests/sec                                  1.425 (OK=1.425  KO=-     )

基本上是5秒延迟,在到了75%的时候,延迟竟然达到了25秒。现在来看一下用Hystrix命令包装后
调用的结果:

================================================================================
---- Global Information --------------------------------------------------------
> request count                                         50 (OK=50     KO=0     )
> min response time                                      1 (OK=1      KO=-     )
> max response time                                   1014 (OK=1014   KO=-     )
> mean response time                                    22 (OK=22     KO=-     )
> std deviation                                        141 (OK=141    KO=-     )
> response time 50th percentile                          2 (OK=2      KO=-     )
> response time 75th percentile                          2 (OK=2      KO=-     )
> mean requests/sec                                 48.123 (OK=48.123 KO=-     )

奇怪的是,测试到了75%的时候时间竟然是2毫秒!这怎么可能呢!然而用了Hystrix提供的优秀工具后,
结果已经很明显了。现在是本次测试的Hystrix控制台视图。

这里的前10个请求已经超时,任何超过Hystrix默认时间1秒的,一但前10个交易失败后,命令就会堵塞其他客户对远程服务的请求。
,因此会有较低的响应时间。为什么这些交易没有显示失败呢,这是因为这里会有一个反馈,优雅的告诉用户请求失败了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值