ITPub博客

首页 > 云计算 > 容器服务 > idou老师教你学Istio :5分钟简析Istio异常检测

idou老师教你学Istio :5分钟简析Istio异常检测

原创 容器服务 作者:CCE_huawei 时间:2019-02-22 10:38:09 0 删除 编辑

异常检测


异常检测和踢出异常主机是一个动态检查上游主机是否正常工作,对不健康主机进行移除的过程。异常检测是一种被动健康

检查,根据返回状态码来判断是否满足移除条件,最后将主机移除,首先我们来了解下驱逐算法。


从上图中,可以看出来主机异常时首先会检查是不是有主机已经被移除了,如果没有被移除,那么直接移除这个不健康的主

机,如果有主机被移除,则会率先检测是否超过移除阈值(maxEjectionPercent),如果超过这个阈值,则不会有任何行为

发生,如果没超过这个阈值,那么则会将该主机移除一段时间,这段时间后则会将主机放入负载均衡池中供下游主机选择并

分发请求。


什么是Panic_Threshold?


在负载均衡的过程中,Envoy只会考虑健康的上游主机。然而,如果健康主机的比例过低,Envoy将会无视健康状态分发所有

的请求,这就是所谓的Panic Threshold,这个阈值默认为50%。这个设计的目的是防止大规模主机崩溃导致整个集群负载

过高。Panic阈值需要和优先级一起配合工作。如果在某个优先级下健康主机数少了,Envoy将会将一些流量转移到低优先级

的主机。如果在低优先级主机中,Envoy发现足够数量的的健康主机。Envoy将会无视Panic阈值。如果各个优先级健康程度

都是100%。Envoy将忽略panic阈值而根据既定负载均衡算法路由流量。如果整体健康程度低100%,envoy认定没有足够数

量健康的宿主机,但是他仍会给所有优先级的主机分发流量。但是如果给定优先级的健康宿主机比例低于了Panic阈值,这时

候对于这部分优先级的宿主机,所有流量将会分发给这部分宿主机而不考虑他们的健康状态。


我们定位到代码中来看下Panic Threshold是如何配置和工作的。


如图,我们可以看出healthy_panic_threshold被默认设定为50%。


在判断流程当中,Envoy先会拿到实时的panic_threshold值,然后通过计算健康的hosts数量与总hosts的数量比值来比较。


在Envoy种有一个hostSourceToUse的方法,这个方法则是作为负载均衡的一部分,来将可用的hosts作为对象返回给调用方。

其中包含很多种情况,我们在此只列举处在panic状态下的情况。如下图,若isGlobalPanic方法返回True也就是说集群内处

在Panic模式,首先统计数据上会记录一次相应的数据,再次可用hosts列表将会包含所有存在的hosts而无视他们的健康状态。



熔断的触发与实现


Istio现在本身支持的四个参数是:连续错误个数,检测周期,主机移除比例以及基本移除时间。这四个参数看上去可以大致

归类一下,连续错误个数和检测周期有点像是触发条件,但实际上真正的触发条件只有一个连续错误个数也就是

consecutive_5xx。主机移除比例和基本移除时间,更像是熔断结果。我们接下来将这四个参数逐一分析下作用和实现。


Consecutive_5xx:设置的是5xx以上错误的个数。Envoy中的putHttpResponseCode方法根据请求结果的http状态码来进行

统计。如果返回状态码不高于500则会设定envoy统计数据中consecutive_5xx为0并且结束方法,若返回码高于500则需要进

行两次判断。首先判断状态码是否是502,503以及504,如果是则会首先将gateway failure 统计数据自增1,而后判断是否

触发了gateway failure的熔断,这部分和istio设定的参数关系不大,我们暂不展开。同样即便是Gateway failure或者返回值

为500,501,consecutive_5xx这个统计数据也会自增1然后和设定的熔断条件进行比较(consecutive_errors)。



如过consecutive_5xx和配置中的比较相等,则会触发相应的onConsecutive5xx方法,这个方法则是通知主线程,这个主机

发生了触发了5xx错误熔断。


有趣的是我们没展开的gateway failure达到触发条件也是会触发这个通知主线程函数,只不过参数上传入的是gateway 

failure这个参数。这个通知方法内会触发onConsecutiveErrorWorker,正是这个方法最重隔离主机。


我们在分析隔离主机之前先来分析另一个参数MaxEjectionPercent,这个参数是最大主机隔离比例。在ejectHost这个方法

中,首先会获得已配置的max_ejection_percent这个参数的值,若果没有配置则会引用默认的10%。在截图中,我们可以看

出如果ejected_percent如果小于max_ejection_percent,就会对主机进行移除操作。此时我们分析下,如果我们设定为

1%,即便移除后ejected_percent比例高于max_ejection_percent也会执行移除行为,类似向上取整。例如,10个主机,

设定移除比例为11%,则最多会移除2个主机而不是1个。如果我们将max_ejection_percent设成0又会发生什么呢?是否

像我们想象的那样一个都不移除因为毕竟0<0这个条件是不成立的。


我在Istio中对应的destinationrule中将max_ejection_percent设置为0,但是发现还是会熔断1个。进而去查询istio-proxy的

配置,发现max_ejection_percent并未配置下去,也就是说这个值采用的默认10%。在查询Istio中的代码applyOutlier

Detection方法中找到。


只有在maxEjectionPercent大于0的时候才会采用这个值,否则不会采用该值,也就是说如果我们配了0下去,这个数值不会

转配到Envoy上,这也就解释了为什么Envoy中的configure_dump中并没有找到maxEjectionPercent所配置的0,并且还解

释了为什么我们认为配置了0,还是会有上游主机熔断这个情况发生,因为使用了Envoy默认的10%。



Interval


Interval限定的是检测周期,即多久会检测一次上游主机返回的Http code来断定是否需要对齐采取熔断策略。其实检测的这

种行为都是由Detector来执行的,interval就是赋予detector的一个定时基准。 


首先在armIntervalTimer方法中,启用定时器,定时器时间会读取配置的interval,如果没有这个配置则会启用默认的10s,

如下图:


当detector initialize的时候会直接启动这个定时器,也就是每过预设的一段时间detector会检查所有的主机的状态。


若这个主机没有处在eject状态则不会做任何行为,如果这个主机处于被隔离的状态,则会检测他移除时间和现在时间相比,

是否满足召回条件。上图中的checkHostForUneject就是专门检查主机状态和判断是否要召回的方法。


介绍这个方法就要提到熔断的最后一个参数baseEjectionTime这个参数意味最小隔离时间,实际隔离时间为最小隔离时间与

隔离次数的乘积。在checkHostForUneject这个方法中,如果主机的健康检查为健康则会直接return不作任何行为,如果主

机的健康检查并不健康,则会读取baseEjectionTime而后通过计算与隔离次数的乘积得出应当被隔离的时间。当前时刻的时

间会以参数的形式传递进来,now和主机最后一次移除相减得出实际隔离的时间。如果应当被隔离的时间小于等于实际被隔

离的时间则会将主机召回并且重置统计参数,反之则不会有任何行为。


异常点检查仍有许多istio未开放的参数,例如GatewayFailure、SuccessRate、最小健康实例数等。其实现上和负载均衡,

健康检查等特性有较强的关联,许多细节仍需分析和实验。


相关服务请访问


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/69908804/viewspace-2636663/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-01-28

  • 博文量
    46
  • 访问量
    47438