SpringCloud使用Hystrix实现后备和仓壁模式

前几章我们讲解了客户端负载均衡模式、断路器模式,这一张我们讲解一下后备模式和舱壁模式。

后备模式

顾名思义,后备模式指的是当Hystrix检测到我们的请求没有任何反应的时候采用另外的方案。
上代码

在这里插入图片描述
我们看到我在@HystrixCommand注解中传入一个参数 fallbackMethod 并赋值为我们当前类的一个方法名(一定要是当前类的方法名)

当Hystrix检测请求长时间没有响应的时候就会执行与fallbackMethod 值相同的(在当前类)的方法。后备模式很容易实现。

舱壁模式

(这一块的东西实在太多了)

讲解的东西实在不想手撸了,复制别人的。
在一个基于微服务的应用程序中,您通常需要调用多个微服务完成一个特定任务。不使用舱壁模式,这些调用默认是使用相同的线程来执行调用的,这些线程Java容器为处理所有请求预留的。在高服务器请求的情况下,一个性能较低的服务会“霸占”java容器中绝大多数线程,而其它性能正常的服务的请求则需要等待线程资源的释放。最后,整个java容器会崩溃。舱壁模式能将远程调用隔离在各个远程调用自己的线程池中,因此单个性能出问题的服务能得到控制,java容器也不会崩溃。
Hystrix将远程服务的请求托管在一个线程池中。即默认情况下,所有Hystrix命令(@HystrixCommand)共享同一个线程池来处理这些请求。该线程池中持有10个线程来处理各种远程服务请求,可以是REST服务调用、数据库访问等。如下图所示:

在这里插入图片描述

image.png

@HystrixCommand的默认配置适用于只有少量远程调用的应用。幸运的是,Hystrix提供了简单易用的方法实现舱壁来隔离不同的远程资源调用。下图说明了Hystrix将不同的远程调用隔离在不同的“舱室”(线程池)中:

在这里插入图片描述

实现这种隔离的线程池,需要使用到@HystrixCommand注解提供的其他属性。接下来,我们会:

为方法getLicensesByOrg()设置一个隔离的线程池
设置该线程池的线程数
设置队列的容量,该队列的作用是当线程池中的线程都处于工作状态,接下来的请求会进入该队列。
下面的代码演示了如何自定义舱壁:

@HystrixCommand(
        fallbackMethod = "buildFallbackLicenseList",
        threadPoolKey = "licenseByOrgThreadPool",
        threadPoolProperties = {
            @HystrixProperty(name = "coreSize",value="30"),
            @HystrixProperty(name="maxQueueSize", value="10")
        }
)
public List<License> getLicensesByOrg(String organizationId){
    randomlyRunLong();
    return licenseRepository.findByOrganizationId(organizationId);
}

上面代码中涉及到几个新的@HystrixCommand暴露的属性。第一个是threadPoolKey,这对于Hystrix来说是新建一个线程池的信号,threadPoolKey的值则是线程池的标识。如果只是配置了threadPoolKey,那么Hystrix会使用默认配置来初始化该线程池。
而若要自定义新建的线程池,则需要使用另一个属性:threadPoolProperties。该属性接收一个@HystrixProperty数组,这些HystrixProperty就是用来配置新建的线程池。比如,可以使用coreSize来配置线程池的容量。
当然也可以设置一个队列,来应对当线程池繁忙的情况。通过maxQueueSize来设置该队列的容量。当请求的数量超过队列的容量,其它的请求会迅速失败返回,直到队列又有空闲的“位置”。
对于属性maxQueueSize,有亮点需要注意。第一,如果value值设置为-1,Hystrix会使用SynchronousQueue来实现该队列。同步队列意味着,当线程池繁忙时,就不再接收其它请求,直接迅速失败返回,可以粗略理解为该队列不存在。当设置一个大于1的值时,Hystrix会创建一个LinkedBlockingQueue,这样会让后到的请求排队等候线程池的线程完成请求处理。
第二,Hystrix允许我们使用SizeRejectionThreshold属性来动态变更队列的容量,但该属性只有在maxQueueSize的value值大于0的时候才能生效。而maxQueueSize属性的值只能在线程池初始化时设置,所以当maxQueueSize为-1时,将无法再变更队列的容量,因为队列是同步队列。
最后,我们应该如何设置一个合适的线程池容量呢?Netflix建议:
每秒处理请求的峰值 × 99%平均响应时间 + 缓冲线程数
然而,在服务正式部署之前,我们是无法知道服务的性能为几何。这里有一个指标可以作为参考,当目标远程资源正常的情况下,调用还会出现超时,那么线程池的容量就需要调整了。

作者:sprinkle_liz
链接:https://www.jianshu.com/p/6c574abe50c1
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

(关于Hystrix还有许多东西,想深入了解的可以查阅相关资料)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值