不得不知道系列之探活机制

原创
03/13 20:55
阅读数 1K

服务探活机制属于健康检测范畴,而服务健康检测关系到故障恢复,进而属于高可用领域。为什么说是探活而不是说健康检测(健康检查)是因为,存活与健康严格上来说不是等号的。就像一个人还活着,但是不代表他是健康的,服务也是如此。被探测节点收到探测请求后将自身健康状态返回去,那么探活能力就可以升级为健康检查能力,在实际应用中,我们都会把探活机制作为健康检测的能力使用。

探活是什么?

探活机制是当前很多高可用服务的基础能力,我们时刻都在使用探活机制,我们似乎没有关注过探活机制的理论。

探活是指通过技术手段检测服务的存活状态。

我们时刻都在使用探活,达到集群的高可用设计,小到网络连接。我们举几个例子:

  • TCP Ke- ep-Alive的探活-;

  • 进程是否还在存在的监控;

  • 主机探活检测;

  • Nginx的节点探活;

  • 服务注册与发现的节点探活;

  • MySQL集群高可用机制(MHA);

由此可见,探活检测一直就在我们的身边,你看着这篇博文的时候他就在你的网络里。这项技术就想空气一样,我们时常忽略它的存在了。

探活机制分类

探活说明需要有两个节点,一个是探测节点另一个就是被探测节点。 在不同的系统中,叫着不同的名字。MHA中探测节点成为Manager,被探测节点为master。redis哨兵机制中探测节点成为Sentinel,被探测节点成为mater。

探测节点和被探测节点可以根据它们的运行方式、部署方式、使用协议的方式等等都有不同的分类。

探测方向

探测方式主要是探测节点主动还是被探测节点主动的方式。如果是探测节点主动发起探测请求,则属于主动探测;如果被探测节点主动发送心跳给到探测节点汇总,则属于被动探测。对于被动探测而言,何尝不是一种特殊的主动探测呢。

探测状态

一般来说,被探测节点只有两种状态,存活或死亡。由存活到死亡探测状态转变称之为探死,由死亡到存活的探测状态转变称之为探活,我们通常通常为探活即可。状态转变的重要指标——超时时间和失败次数,在实际实践中,哪怕服务还存活,但在指定时间内没有响应就认为是失败。

探死

探死的方式在开发中更常使用到,可以简要描述为:

  1. 探测节点持续先被探测节点发送探测请求。
  2. 在被探测节点健康存活的情况下,返回指定响应。如果连续探测失败次数达到一定的阈值,则将被探测节点的状态变为“死亡”或“失败”。
  3. 在被探测节点“死亡”或“失败”状态下,如果连续探测成功次数达到一定的阈值,则将 被探测节点的健康状态变为“正常”或“存活”。

不论是探测节点主动去探测被探测节点,还是"被探测节点"通过心跳的方式上报状态给到"探测节点"方式,均为探死方式。关注都是服务的状态是否转变为了“死亡”状态。

探活

探活方式并不是说探测节点和被探测节点的角色调换,而是"探活"方式,关注被探测节点失败“活”过来了。描述一下:

  1. 在被探测节点是存活状态时,探测节点和被探测节点不会主动探测。
  2. 被探测节点出现了异常,无法处理正常业务了,如负载均衡器下面的服务故障了,无法处理请求。通过各种管道通知探测节点该被探测节点处于"死亡"状态,探测节点才会向它发起探测请求。
  3. 在 被探测节点为“死亡”的状态下,如果连续探测成功次数达到一定的阈值,则将探测节点的状态变为“存活”。

那么如何发现被探测节点处于"死亡"状态了?通过正常业务流量。比如在网关和负载均衡器可以通过正常的业务流量请求,如果服务无法处理请求,这判定为死亡状态,由探测节点接受后续的探活。也就是说被动探活主要应用在网关和负载均衡器中。因为网关和负载均衡器的部署节点可以有很多个,一个机房可以部署几百个甚至上千个网关节点,那么网关对下游的探测流量就是非常大流量的。

假设mjq机房部署,1000台网关节点,该机房服务有100000个节点,设定探测间隔为3s:

  • 主动探活:每个服务节点收到探测请求量为333.3QPS,每个网关对外发送探活请求量33333.3次/s。如果服务使用使用心跳方式向网关上报状态,那么每个网关收到的心跳请求也是很大的。
  • 被动探活:网关节点不会主动探活服务节点,那么这个探测流量可以数量级的减少了。除非是机房后很多服务都宕机了,最坏的情况也就是退变成主动探活。

通过这个示例,我们可以再讨论一下主动探活和被动探活的区别和局限性。

主动探活在大规模水平扩展方面受到制约,容易造成"探测风暴"。

"探活方式"采用了正常流量作为探活请求的替代,有好处也有局限,好处是:

  1. 在被探测节点状态为存活时候,不需要探测节点启动探测请求,节省了双方的性能损耗。
  2. 正常业务流量请求较高的时候,能更快发现被探测节点的状态死亡变更。

成也萧何败也萧何,在如下几个场景下被动探活的适用性就不足了:

  1. 业务正常流量低于主动探活流量,可能导致被探测节点不健康或者死亡不能及时发现发现。
  2. 在服务没有幂等能力情况下,正常流量无法进行重试。
  3. 在容器化中服务节点的ip是变化的,一旦节点迁移原来的探测路径就不复存在,可以在被动探活机制加上过期时间。

小结

主动探活和被动探活有优点也有局限性,在实际实践中我们可以将两者结合起来应用:在小规模集群的探活可以采用主动探活为主,通过调整探测间隔,降低探测流量。在大规模集群中对大流量服务采用被动探活,对小流量服务采用主动探测。

部署方式

根据探测节点的部署方式(探测节点和被探测节点的相对位置)可以分为集中式探活和分布式探活。

集中式探活

一个或者一组探测节点集中部署在同一个网络中,通过一定的负载均衡算法分配被探测节点进行探活操作。

集中式探活可以降低探测量和更容易获取到全局服务状态列表,但是无法应对网络分区的情况。在网关实践中可以采用集中式探活,发现有失败的服务节点,通知给到网关节点进行二次探测确认并且网关节点的状态优先级高于探测节点的。

分布式探活

探测节点和被探测节点各自部署在不同的位置,每个探测节点独立维护自己探活节点的状态。在现实世界中也是符合的,每个被探测节点所处的机房、网络、服务器都有不同,其健康状态在外部看来可能会有不同的结果。

如上图,每个探测节点都有被探测节点的状态信息,那么此时,我们想得到一个汇总后的节点状态,如何获取到呢?在分布式健康检查方式下,仅从一个探测节点实例获取 状态列表信息是不全面的,很可能出现“以偏概全”的情况;而如果从所有探测节点实例中读取状态信息并进行汇总,在探测节点数量比较多的情况下,这是一种很不经济的方案;那么我们可以尝试使用"过半存活"原则考虑多种因素进行筛选策略。

小结

正如《Software Engineering at Google》: three critical differences between programming and software engineering: time, scale, and the trade-offs at play.(编程和软件工程之间有三个关键的区别:时间、规模和权衡取舍)。随着时间的推移,系统规模的演变扩大,之前合适的探测方式也需要进行相应的演进。

总结

探活机制是高可用的基础能力,用于确认服务的存活状态。重点的指标:

  1. 实效性:多久可以发现状态变化
  2. 误报率:探测错误的概率;

探测机制不论是按照探测状态还是部署方式分类,在应用中将结合使用,效果会更好。

附录

https://www.cnblogs.com/zhuochongdashi/p/15796859.html

https://github.com/baidu/bfe-book

https://github.com/qiangmzsx/Software-Engineering-at-Google

展开阅读全文
加载中

作者的其它热门文章

打赏
1
0 收藏
分享
打赏
0 评论
0 收藏
1
分享
返回顶部
顶部