首页 > 其他分享 >RPC框架的健康检测机制

RPC框架的健康检测机制

时间:2023-02-06 19:36:11浏览次数:51  
标签:调用 服务 框架 检测 接口 RPC 心跳 节点

服务发现的作用:实时感知集群IP的变化,实现接口跟服务集群节点IP的映射。超大规模集群更要考虑最终一致性。“推拉结合,以拉为准”。

1 健康检测

因为有了集群,所以每次发请求前,RPC框架会根据路由和负载均衡算法选一个具体的IP地址。为保证请求成功,就要确保每次选出来的IP对应连接是健康的。

但调用方跟服务集群节点之间的网络状况瞬息万变,两者之间可能会闪断或网络设备损坏等,怎么保证选出来的连接一定可用?

终极的解决方案是让调用方实时感知到节点的状态变化,这样他们才能做正确选择。像开车一样,车有各种各样的零件,我们不可能在开车之前先去挨个检查下他们的健康情况,转而是应该有一套反馈机制,比如今天我的大灯坏了,那中控台就可以给我提示;明天我的胎压不够了,中控台也能够收到提示。汽车中大部分关键零件的状态变化,我作为调用方,都能够第一时间了解。

回到RPC框架里,专业一点的词来就是服务的健康检测。

2 生产事故

线上业务的某个接口可用性并不高,十次调用总有几次失败。

查看监控数据后,发现只有请求具体打到某台机器才有这问题,即集群中有某台机器异常。建议他们先“问题机器”下线。

接口调用某台机器时已出现不能及时响应了,为何RPC框架还继续把请求发到这台有问题机器?即在调用方角度,它没有觉得这台服务器异常。

于是查看问题时间点的监控和日志:

  • 通过日志发现,请求确实会一直打到这异常机器,因为日志有很多超时的异常信息
  • 监控上看,这台机器还是有一些成功请求,这说明当时调用方跟服务之间的网络连接没有断开。因为若连接断开后,RPC框架会把该节点标识为“不健康”,不会被选出来用于发业务请求
  • 深入看异常日志,发现调用方到目标机器的定时心跳会有间歇性失败
  • 从目标机器的监控,可看到该机器的网络指标有异常,出问题时间点TCP重传数比正常高10倍以上

基本可得:那台问题服务器在某些时间段出现网络故障,但也还能处理部分请求。即它处于半死不活状态。但还没彻底“死”,还有心跳,这样,调用方就觉得它还正常,所以就没有把它挪出健康状态列表。

所以,更大问题是服务检测机制有问题,有的服务本来都已新冠晚期,但还以为人家只是普通感冒。

3 健康检测的逻辑

当服务方下线,正常情况下我们肯定会收到连接断开的通知事件,在这事件里直接加处理逻辑不就行?

是的,汽车案例里检测都是这样做的。但这不行,应用健康状况不仅包括TCP连接状况,还包括应用本身是否存活,很多情况下TCP连接没断开,但应用可能已“僵死”。

所以,常用检测方法即心跳,服务调用方定时问服务提供方,“兄弟,还好吧?”,然后服务提供方如实地告诉调用方它目前状态。

服务方的状态

① 健康状态

我很好。建立连接成功,并且心跳探活也一直成功

② 亚健康状态

我生病了。建立连接成功,但是心跳请求连续失败

③ 死亡状态

没回复。建立连接失败。

节点的状态会根据心跳或重连结果而动态变化:

RPC框架的健康检测机制_提供方

初始化时,若建立连接成功,那就是健康状态,否则死亡状态,没有亚健康中间态。

若健康状态的节点连续出现不能响应心跳请求情况,就标记为亚健康,即服务调用方会觉得它生病了。

生病之后(亚健康状态):

  • 若连续几次都能正常响应心跳请求,就可转回健康状态,证明病好了
  • 若病一直好不了,断定为是死亡节点,死亡之后还需要善后,如关闭连接

死亡还有复活的机会。如果某个时间点里,死亡节点能重连成功,就重新标记为健康状态。

当服务调用方通过心跳了解节点状态后,每次发请求时,优先从健康列表里选择一个节点。若健康列表为空,为提高可用性,也可尝试从亚健康列表里面选个。

3 具体解决方案

一个节点从健康状态过渡到亚健康状态的前提:“连续”心跳失败次数必须到达某一个阈值,如3次。

而场景里,节点心跳日志间歇性失败,时好时坏,失败次数根本没到阈值,调用方觉得它只是“生病”,并且很快就好了。怎么解决?改下配置,调低阈值?是的,这是最快解决方法,但治标不治本:

  • 调用方跟服务节点之间网络状况瞬息万变,出现网络波动的时候会导致误判
  • 负载高情况,服务端来不及处理心跳请求,由于心跳时间很短,会导致调用方很快触发连续心跳失败而造成断开连接

问题核心是服务节点网络有问题,心跳间歇性失败。现在判断节点状态只有一个维度,那就是心跳检测,那是不是可以再加上业务请求维度?

但又发现新麻烦:

  • 调用方每个接口的调用频次不一样,有的接口可能1秒内调用上百次,有的接口可能半个小时才会调用一次,不能把简单的把总失败的次数当作判断条件
  • 服务的接口响应时间也是不一样的,有的接口可能1ms,有的接口可能是10s,也不能把TPS至来当作判断条件

找到可用率突破口,应该相对完美。可用率的计算方式:

某一个时间窗口内,接口调用成功次数的百分比(成功次数/总调用次数)

当可用率低于某个比例就认为该节点异常,挪到亚健康列表:

  • 既考虑了高低频的调用接口
  • 兼顾接口响应时间不同的问题

5 加完心跳机制,就万事大吉了吗

不是,因为检测程序所在机器和目标机器之间的网络可能还会故障,就会误判。你以为人家已经生病或者挂了,其实是心跳仪器坏了。

有个办法可减少误判率,把检测程序部署在多个机器里面,分布不同机架,甚至不同机房。因为网络同时故障概率低,所以只要任意一个检测程序实例访问目标机器正常,就可以说明该目标机器正常。

6 总结

健康检测帮助我们从连接列表里面过滤掉一些存在问题的节点,避免在发请求的时候选择出有问题的节点而影响业务。但是在设计健康检测方案的时候,我们不能简单地从TCP连接是否健康、心跳是否正常等简单维度考虑,因为健康检测的目的就是要保证“业务无损”,所以在设计方案的时候,我们可以加入业务请求可用率因素,这样能最大化地提升RPC接口可用率。

正常情况下,我们大概30S会发一次心跳请求,这个间隔一般不会太短,如果太短会给服务节点造成很大的压力。但是如果太长的话,又不能及时摘除有问题的节点。

除了在RPC框架里面我们会有采用定时“健康检测”,其实在其它分布式系统设计的时候也会用到“心跳探活”机制。

比如在应用监控系统设计的时候,需要对不健康的应用实例进行报警,好让运维人员及时处理。和咱们RPC的例子一样,在这个场景里,你也不能简单地依赖端口的连通性来判断应用是否存活,因为在端口连通正常的情况下,应用也可能僵死了。

那有啥其他办法能处理应用僵死的情况吗?我们可以让每个应用实例提供一个“健康检测”的URL,检测程序定时通过构造HTTP请求访问该URL,然后根据响应结果来进行存活判断,这样就可以防止僵死状态的误判。你想想,这不就是咱们前面讲到的心跳机制吗?

FAQ

有服务需通过银行安装在我们后台软件向银行分发交易。这个软件我们在使用过程发现会无故挂掉,为了能及时检测这种情况。 通过 openresty 写个小插件、通过 http 接口访问银行软件,查看银行软件是否挂了。然后接入钉钉 webhook,触发机器人报警。 由于当时是将 openresty 跟银行软件部署在同一台物理机器上去。某一天,整台机器挂了,报警机制当然也失效了。通过这件事,我现在每次部署服务时,会注意将服务部署在不同物理机器,防止意外。

成功次数/调用总次数,建议加上总次数阀值。如果2次,一次成功,一次失败,就可能误判。例如调用总数>10次以上,成次数/调用次数<50%,才比较准确

还是需要分场景对待的,没有最好的,只有最合适的。

心跳检测需要分两个纬度,一个机器本身的,一个是应用,单纬度肯定会出问题

之前使用过返回状态保存在MQ中,有专门的消费者去消费消息,其中要是失败率大于阈值,直接调用注册中心,下线该服务,同时使用agent机制,自动重启有问题的服务,之后要是还会出现失败,则报警发出,人工介入。

失败率统计是难点,需要考虑是否有网络设备坏或者不同idc问题

健康检测:调用方向服务方发送心跳检测,如果超过3次(阈值可以设置)未响应则认为服务节点挂掉。 会存在的遇到的问题 \1. 服务方会出现心跳正常响应,但是服务间歇性响应超时(亚健康状态),会导致调用方误判;可以用可用率的思路来解决。 \2. 调用方心跳机制出现问题,导致误判服务方挂掉;可以用调用方集群部署,其中一台调用显示正常则认为正常的办法来减少误判。 Dubbo通过IdleStateHandler设置定时任务,服务空闲发送心跳,实现健康检测 ​​http://dubbo.apache.org/zh-cn/blog/dubbo-heartbeat-design.html​

老师我认为心跳检测不应该接口的调用方来检测,这样的话调用接口的客户端量很大时,只是心跳检测就会把服务提供方的资源打满,而且当接口服务提供方很多时,客户端每个ip去健康检测也是不可能的

不一定要接口纬度,一般情况下多个接口直接会共享tcp连接的,可以用tcp连接纬度

1.上面说的基于失败率统计的方案,不就是熔断吗? 2.心跳检测,这个从调用方发心跳到服务方,会不会太重,基于熔断是不是就可以了 3.后面又说心跳检测可以放在多台机器去综合判断,刚刚不是说由调用方发起心跳吗?又变成第三方心跳检测了? 我理解这里有注册中心做心跳,再加熔断,失败重试等就可以了,不知道对不对

调用方到提供方之间心跳正常才能保证链路没有问题

心跳检测,单一纬度的标准始终差点意思。还是要结合业务场景,多维度判断,来保证结果准确性。例如 连续失败是最直接的纬度,可以综合考虑变更为 单位时间内失败次数,或单位次数的成功率

RPC 框架的心跳检测怎么做的呢?只听说过心跳检测这个概念,但在代码层面如何做,没有概念。看到老师在最后提到检测应用是否可用,可以在应用实例中开一个 url 供检测程序发 http 请求检测。但非应用级别的心跳检测也是这样做的吗?

定时发心跳消息是最简单的方法,通过判断是否正常响应

可用率这个指标具体怎么实现呢?因为一般使用RPC框架都是三方框架,我们是需要自己对三方接口进行重新实现吗?

看看有没有插件支持

1:心跳探活核心要点在于 第一及时 第二准确 第三全面,网络环境瞬息万变,需要考虑探活机器本身是否OK?探活的机制是否OK? 探活机制的设置应视情况而定,可以是节点级?也可以是服务级?为了防止因网络通信问题误判,可以设置多个探活节点。为了使探活更准确,可以假如可用率,调用次数等维度。

你以为别人挂了其实是自己挂了?

检测的目的防止别人挂

如果在多个机房部房部署探活程序,如果部分检测有问题 部分检测没有问题,这个状态需要怎么判断,又该怎样同步给所有探活程序?

多机房主要担心跨机房网络问题,只要有存活的就认为存活。

健康检查这套逻辑需要业务和运维的配合实现,业务要提供heath check的endpoint,运维要调用这个endpoint来查看服务的情况,所以在进一步,一些通用的框架会自动集成health check的功能并可以通过配置打开,当新服务上线的时候,监控检查功能会自动提供。

心跳检测文中说是调用方定时去看看提供方是否存活。但是平常好像不是这么做的,会有一台专门做健康检查的机器定时去调用健康检查接口,是说这两种方式都是可以的么 觉得第一种会不会做起来成本比较高?

用其他机器去检查反映出来的结果不一定准,可能中间经过的网络设备不一样。

标签:调用,服务,框架,检测,接口,RPC,心跳,节点
From: https://blog.51cto.com/u_11440114/6040293

相关文章

  • 快速上手python的简单web框架flask
    目录简介web框架的重要组成部分快速上手flaskflask的第一个应用flask中的路由不同的http方法静态文件使用模板总结简介python可以做很多事情,虽然它的强项在于进行向量运......
  • 触摸屏驱动程序框架分析
    触摸屏驱动程序,用于人机交互lcd上的独立的一个屏,这里指的是电阻屏。下面来分析一下内核自带的触摸屏驱动框架,便于我们自已编写触摸屏驱动程序触摸屏驱动使用的是Input_sub......
  • django框架之drf(部分讲解)
    一、各个视图子类两个视图基类五个视图扩展类九个视图子类-----》视图类,不需要额外继承GenericAPIView,只需要继承九个州其中之一,就会有某个或某几个接口路由......
  • 软件测试计划怎么制定?专业第三方软件检测方案推荐
    一、软件测试是什么?软件项目测试计划是描述测试目的、范围、方法和软件测试的重点等的文档。对于验证软件产品的可接受程度编写测试计划文档是一种有用的方式。......
  • 手写spring框架
    当我们自己想实现一个Spring框架的时候,想想我们需要实现哪些功能。先从最基础的部分开始,我们首先需要一个容器,我们可以通过这个容器获取bean。那容器里的bean是从哪来的呢?......
  • 开源即时通讯IM框架 MobileIMSDK v6.3 发布
    一、更新内容简介本次更新为次要版本更新,进行了若干优化(更新历史详见:码云ReleaseNodes)。可能是市面上唯一同时支持 UDP+TCP+WebSocket 三种协议的同类开源IM框架。二......
  • 腾讯出品小程序自动化测试框架【Minium】系列(六)常见组件的处理
    写在前面我发现一件神奇的事,当你学一门新技术或者新的知识点遇到不会的时候,真的可以先放一放,第二天再去学习,也许说不定也就会了。为什么这么说?昨天文章断断续续的写了近......
  • 东方联盟创始人郭盛华:正在全球范围内检测到这些勒索软件攻击
    VMwareESXi管理程序是新一波攻击的目标,旨在在受感染的系统上部署勒索软件。“这些攻击活动似乎利用了CVE-2021-21974,自2021年2月23日以来已经提供了补丁,”东方联......
  • 一个简单的.net 6控制台程序框架
    一个简单的.net6控制台程序框架其中包括,1.使用IOC控制接口的生成,2.使用OPtions来操作配置文件,3.使用nlog来控制日志4.自动获取所有的backgroundService并运行1.Pro......
  • Hugging News #0203: 3.3 MB 的文生图模型、RHLF 训练框架、手机上能跑的 Transformer
    每一周,我们的同事都会向社区的成员们发布一些关于HuggingFace相关的更新,包括我们的产品和平台更新、社区活动、学习资源和内容更新、开源库和模型更新等,我们将其称之为......