欢迎来到深圳中鲁粤科技有限公司网站!

收藏本页 | 常见问答 | 在线留言 | 网站地图

科技资讯

日本加野麦克斯Kanomax
专注某某行业十余年
咨询热线13800000000

热门关键词:示例页面

科技资讯

刷vip网站卡盟_免费刷推广链接的网站_猪猪网站

文章分类:文章中心人气:41 次访问时间:2024-05-02 18:05

自助下单地址(拼多多砍价,ks/qq/dy赞等业务):点我进入

认识 Hystrix

Hystrix是Netflix开源的容错框架。 它可以做几件事:

为什么要做线程隔离

在一个复杂的分布式系统中,通常会有很多依赖关系。 如果应用程序不能将故障与依赖关系隔离开来,应用程序本身就有被拖垮的风险。 在大流量网站中,一旦单个后端出现延迟,所有应用资源都会在几秒内耗尽,也就是我们常说的雪崩效应。

比如我们现在有查询订单、查询商品、查询用户三个业务调用,而这三个业务请求都依赖第三方服务——订单服务、商品服务、用户服务。 这三个服务都是通过RPC调用的。在查询订单服务时,如果线程阻塞,此时有大量查询订单请求进来,容器中的线程数会不断增加,直到CPU资源用完耗尽到 100%,整个服务对外不可用。 在集群环境中是雪崩式的

订单服务不可用,导致请求积压,耗尽系统资源,影响其他服务调用

容错限流原理

对于基本的容错限流方式,主要有以下几点需要考虑:

断路器模式

实现过程是:当断路器的开关断开时(对应图中的绿色),每一个请求进来都是成功的。 当后端服务出现问题,请求错误次数达到一定阈值时,就会触发熔断器,熔断器处于打开状态(对应图中的红色)。 当断路器处于打开状态时,所有传入的请求都会被拒绝。 当然,请求并不是一直被拒绝,而是有弹性的。 它会进入半开状态(对应图中黄色),也就是让一些请求通过并尝试。 如果尝试仍然有问题,则继续进入打开状态。 如果尝试没有问题,就会进入关闭状态。

隔板隔离模式

舱壁隔离模式可以隔离资源,类似于一艘船的舱室都是隔离的,当一个或几个舱室出现问题,比如漏水时,不会影响到其他舱室信号隔离器的原理,从而实现一个效果资源隔离。

容错概念 Hystrix核心概念 资源隔离

信号隔离器的原理_ha11信号隔离变送器_信号隔离分配器

资源隔离的思想参考了上面提到的bulkhead隔离模式。 hystrix中提供了两种资源隔离策略:线程池隔离和信号量隔离。

线程池隔离:线程池隔离会为每个依赖(每个服务提供者)创建一个线程池来处理来自该依赖的请求。 不同的依赖线程池相互隔离。 即使依赖A失败,线程池资源也会被阻塞。 耗尽不会影响其他依赖的线程池资源。

Hystrix通过命令方式将每一类业务请求封装成对应的命令请求,如查询订单->订单命令、查询产品->产品命令、查询用户->用户命令。 每一种Command对应一个线程池。 创建好的线程池放入ConcurrentHashMap中,如查询顺序:

final static ConcurrentHashMap threadPools = new ConcurrentHashMap();threadPools.put(“hystrix-order”, new HystrixThreadPoolDefault(threadPoolKey, propertiesBuilder));

当第二次查询订单请求到来时,可以直接从Map中获取线程池。 具体过程如下:

信号量隔离模式:初始化信号量currentCount=0,每次进来的请求都需要先自增currentCount,然后判断currentCount的值是否小于系统的最大信号量,如果小于最大信号量,则继续执行,大于则直接返回,拒绝请求。

代码如下:

public boolean tryAcquire() { int currentCount = this.count.incrementAndGet(); if (currentCount > (Integer)this.numberOfPermits.get()) { this.count.decrementAndGet(); return false; } else { return true; }}

隔离法

是否支持超时

是否支持熔断

信号隔离分配器_ha11信号隔离变送器_信号隔离器的原理

隔离原理

是否异步调用

如果

线程池隔离

支持,可以直接回

支持,当线程池达到maxSize时,请求会触发fallback接口进行熔断

每个服务使用独立的线程池,请求线程和转发处理线程不一样

可以异步也可以同步,看调用方法

大,大量线程的上下文切换容易造成机器负载高

信号量隔离

不支持,如果阻塞,只能通过调用协议返回(如:socket timeout)

支持,当信号量达到 maxConcurrentRequests 时。 重新请求将触发回退

通过信号量的计数器,请求线程和转发处理线程是同一个

同步调用,不支持异步

小,只是一个柜台

ha11信号隔离变送器_信号隔离器的原理_信号隔离分配器

断路器

断路器的工作原理如下:

Hystrix是基于鼓法的。 每秒产生一个bucket,每产生一个新的bucket就会移除最旧的bucket。 默认值为 10 秒的窗口。 Buckets是内存中的一种数据结构,每个bucket都会记录Metrics的相关数据,比如成功、失败、超时、拒绝等。

当一个HystrixCommand进来的时候,首先会通过allowRequest()方法判断是否允许请求,allowRequest()方法会通过isOpen判断断路器是否打开。 如果断路器闭合,则允许请求通过; 如果断路器打开,则判断睡眠周期是否已过。 如果没有休眠周期则返回false,拒绝请求,休眠周期结束后尝试释放。

isOpen() 方法会根据公式(失败)/(成功+失败)计算失败率。 如果故障率大于阈值,将触发断路器。 公式中成功和失败的数据来自每10秒一个窗口的鼓数据。

对于依赖调用,要么调用成功,要么调用失败(包括异常、超时、拒绝),这些调用的结果都会记录在桶中。 对于调用成功的结果,还要判断断路器开关是否打开,如果打开,则关闭断路器,并重置相关计数器。

降级回退

降级,通常是指交易的高峰期。 为了保证核心服务的正常运行,需要停止一些不太重要的业务,或者当某些服务不可用时,执行备份逻辑,使故障服务快速失效或返回,以保证主业务不受影响。 Hystrix提供的降级主要是为了容错,保证当前服务不受依赖服务失效的影响,从而提高服务的健壮性。

1)哪些情况会进入降级逻辑

断路器打开

线程池/信号量资源不足

执行依赖调用超时

执行依赖调用异常

2)降级回退方法

(1) Fail Fast 快速失败

快速失败是最常见的命令执行方式,命令不会覆盖降级逻辑。 如果在命令执行过程中发生任何类型的失败,它只会抛出一个异常。

(2) Fail Fast静默失败

指在降级方法中通过返回null、空Map、空List或其他类似的响应来完成。

(3) 回退:静态

指在回退方法中返回静态默认值。 这不会导致服务以“静默失败”的方式被删除,但会导致默认行为发生。 例如:应用程序根据命令执行返回true/false来执行相应的逻辑,但如果命令执行失败,则默认为true。

(4) 后备:stubbed

当命令返回具有多个字段的复合对象时,适合以存根的方式回退。

(5) FallBack:通过网络缓存

有时,如果调用依赖服务失败,可以从缓存服务(如redis)中查询旧数据版本。 由于会再次发起远程调用,建议重新封装一个Command,使用不同的ThreadPoolKey与主线程池隔离。

(6) Primary+Secondary with FallBack

有时系统有两种行为——主要和次要,或主要和故障转移。 主从逻辑涉及不同的网络调用和业务逻辑,所以需要将主从逻辑封装在不同的Command中,使用线程池进行隔离。 为了实现主从逻辑切换,可以将主从命令封装在外观HystrixCommand的run方法中,结合配置中心设置的switch进行主从逻辑切换。 由于主次逻辑都是线程池隔离的HystrixCommand,所以看起来HystrixCommand可以使用信号量隔离,不需要使用线程池隔离引入不必要的开销。

请求结果缓存

请求合并

Hystrix 工作流程

对于依赖调用,会封装在一个HystrixCommand对象中。 有四种方法可以执行调用。 一种是同步调用execute()方法,另一种是调用queue()方法进行异步调用。

1.同步执行: execute ,同步,直接返回结果, 该方法有注解的实现

@HystrixCommand public String helloService(){ return restTemplate.getForEntity("http://hello-service/hello",String.class).getBody(); }

2.异步执行: queue ,异步,返回Future,直到调用Future的get方法,才会阻塞,直到得到结果。 在此之前,它是异步执行的。 该方法有注解的实现

@HystrixCommand public Future queueService(){ return new AsyncResult(){ public String invoke(){ return restTemplate.getForEntity("http://hello-service/hello",String.class).getBody(); } }; }

上面两个返回值不同,注意观察。

3.异步执行,observe方法返回一个Hot Observable,因为HystrixCommand是调用observe方法后(异步)执行的,通过subscribe订阅返回的Observable获取处理结果。 案例如下:

@Testpublic void test03() throws InterruptedException { HystrixCommand command = createCommand("this is test03"); Observable observe = command.observe();// observe直接执行run方法,称为Hot Observable System.out.println("observe之后,command就执行了"); Thread.sleep(1000); observe.subscribe(new Action1() { @Override public void call(String s) { System.out.println("通过订阅,获取执行结果:" + s); } });}// 控制台:// observe之后,command就执行了// HystrixCommand执行了!!!// 通过订阅,获取执行结果:this is test03

4、HystrixCommand.toObservable,toObservable方法返回一个Cold Observable,因为这里调用toObservable时HystrixCommand的run方法不会立即执行,需要订阅后执行run方法。 案例如下:

@Testpublic void test04() throws InterruptedException { HystrixCommand command = createCommand("this is test04"); Observable observe = command.toObservable();// toObservable不直接执行run方法 System.out.println("未订阅,command不执行"); Thread.sleep(1000); System.out.println("订阅后,command执行了"); observe.subscribe(); Thread.sleep(1000);}// 控制台:// 未订阅,command不执行// 订阅后,command执行了// HystrixCommand执行了!!!

执行时会判断断路器开关是否打开。 如果断路器打开,则进入getFallback()降级逻辑; 如果断路器关闭,它会判断线程池/信号量资源是否已满。 如果资源已满,则进入getFallback()降级逻辑; 如果未满,则执行 run() 方法。 然后判断run()方法执行是否超时。 超时后,会进入getFallback()的降级逻辑。 如果run()方法执行失败,就会进入getFallback()的降级逻辑。 如果执行成功,会上报Metrics。 Metrics中的数据包括执行成功、超时、失败等数据,Hystrix会计算一个断路器的健康值,即失败率。 当故障率超过阈值时,将触发断路器开关打开。

getFallback()的逻辑是:如果fallback()方法没有实现信号隔离器的原理,直接抛出异常。 此外,回退降级也需要资源。 回退时,需要获取回退信号量。 只有获取fallback成功才能获取到fallback,获取不到信号量。 ,会抛出异常,只有获取到信号量成功才会执行fallback方法,响应fallback方法中的内容。

————————————————

版权声明:本文为CSDN博主“大象999”原创文章,遵循CC 4.0 BY-SA版权协议。 转载请附上原文出处链接及本声明。

原文链接:

相关文章:Hystrix源码阅读(一)HystrixCommand的四种执行方式

关键词:, , , ,

热销产品