← 返回题目列表

健康检查和心跳机制在高可用中有什么作用?

高频 中等 第 4 / 27 题 更新于 2026/07/28
健康检查心跳探活故障检测

简化版

健康检查和心跳用于判断节点是否还能正常服务,是故障摘除、主备切换和自动恢复的基础。设计时要区分进程存活和业务可用,避免探测太粗导致故障漏判,也避免探测太激进导致误判和频繁切换。

详细版

常见探测类型:

  1. 存活检查:进程是否还活着,失败可触发重启;
  2. 就绪检查:实例是否准备好接流量,比如依赖、连接池、配置是否正常;
  3. 业务探活:模拟核心接口调用,判断真实业务链路是否可用;
  4. 心跳上报:节点周期性向注册中心、协调服务或监控系统报告状态;
  5. 指标判断:通过错误率、延迟、队列积压、连接数等判断亚健康。

设计重点是探测口径、失败阈值、超时时间、防抖策略和摘流恢复流程。健康检查不能只返回固定 200,否则服务内部已经不可用也会继续接流量。

完整版教学

一、没有检测就没有自动恢复

高可用系统必须先知道哪里坏了,才谈得上摘除、切换和恢复。健康检查和心跳就是系统的感知器官。应用实例是否能接请求,数据库主库是否还可写,缓存节点是否响应,消息队列是否堆积,都需要被持续探测。

如果没有探测,故障只能靠用户投诉发现。即使有备用节点,系统也不知道什么时候该切。高可用的第一步永远是可观测和可检测。

二、进程活着不等于服务可用

最常见的错误是把健康检查写成:

GET /health -> 200 OK

只要进程没死就返回成功。但真实故障往往不是进程退出,而是线程池满、数据库连接耗尽、下游接口全部超时、配置加载失败、磁盘写满、GC 频繁暂停。此时进程还活着,却无法正常服务。

更合理的做法是把健康检查分层。存活检查只判断进程是否需要重启;就绪检查判断实例是否应该接流量;业务探活模拟关键链路,验证用户真正关心的能力。

三、探测太激进会制造故障

健康检查不是越频繁、超时越短越好。网络偶尔抖动、GC 暂停、瞬时 CPU 抢占都可能导致一次探测失败。如果一次失败就摘除节点,大量节点可能因为短暂抖动被同时摘掉,剩余节点压力暴涨,形成雪崩。

因此健康检查通常会设置连续失败阈值。比如连续 3 次失败才摘流,连续 5 次成功才恢复。恢复时还可以慢启动,让实例逐步承接流量,而不是瞬间吃满。

这个过程叫防抖。高可用里很多动作都需要防抖,因为错误的自动化动作会放大事故。

四、业务探活要轻量但真实

业务探活应该尽量贴近真实链路,但不能太重。比如订单服务可以提供一个只读轻量探活,检查数据库连接、缓存连接、核心配置和线程池状态。不要让探活本身创建真实订单,也不要因为探活频繁访问昂贵 SQL 导致额外压力。

对于依赖很多的服务,健康状态还可以分级:核心依赖失败则不接流量,非核心依赖失败则继续接流量但启用降级。比如推荐服务失败不应导致商品详情服务被判定不可用。

五、心跳机制要处理网络分区

心跳常用于注册中心、集群选主和节点存活判断。节点定期上报状态,如果超过一定时间没有心跳,就被认为异常。

但心跳失败不一定代表节点死了,也可能是网络不通。网络分区下,A 看不到 B,B 也可能看不到 A。如果两边都认为自己应该接管,就会出现脑裂。因此有状态集群通常不能只靠双方互相心跳,还要引入多数派、租约、仲裁节点或中心化协调。

六、健康检查要区分“摘流”和“重启”

很多系统把所有健康检查混成一个接口,结果容易误操作。进程因为某个非核心依赖失败就被重启,会让问题更糟;实例已经不能处理请求却仍然接流量,也会影响用户。更好的做法是区分存活检查和就绪检查。

存活检查回答“这个进程是否已经坏到需要重启”。比如主线程死锁、事件循环卡死、内部状态不可恢复,适合重启。就绪检查回答“这个实例是否应该接收新流量”。比如数据库连接池没准备好、配置还没加载、正在优雅下线,就应该从负载均衡摘流,但不一定重启。

业务探活则更贴近核心能力,可以模拟轻量查询或依赖检查,但不能做高成本操作。三者分开后,系统动作更精确:该重启时重启,该摘流时摘流,该降级时降级。

七、亚健康比彻底宕机更难处理

生产环境里,实例完全宕机反而容易处理;更难的是亚健康:偶发超时、P99 飙升、线程池接近耗尽、GC 暂停、磁盘 IO 抖动、下游慢导致请求堆积。这些情况下健康检查可能仍然成功,但用户体验已经变差。

治理亚健康要结合指标,而不是只靠心跳。可以根据连续错误率、P99 延迟、队列长度、连接池可用连接数、CPU load、GC 时间等综合判断实例状态。负载均衡也可以做离群实例摘除,把明显慢于其他实例的节点临时降权。

面试里如果能讲出“健康检查不仅判断 alive,还要判断 ready 和 healthy degraded”,会比只说心跳包高级很多。高可用的目标不是发现死亡节点,而是尽早发现正在拖累系统的异常节点。

八、常见误区与追问

这道题要紧扣「健康检查与心跳」本身回答,不能把它混成泛泛的高可用套话。面试官通常不是只听定义,而是看你能不能把适用场景、关键流程、失败边界和工程取舍串起来,尤其要说明故障域、冗余、健康检查、切换流程、RPO/RTO 和演练结果。

回答层次要讲清的内容容易漏掉的边界
核心结论健康检查判断服务是否可用,心跳上报存活状态,关键是区分进程活着和业务真的可用不要停在名词解释
流程机制客户端或注册中心探测 -> 服务返回健康状态 -> 连续失败计数 -> 摘除异常实例 -> 恢复后预热加回 -> 监控误判和漏判要说清触发点、状态变化、确认点和失败兜底
工程取舍每 5 秒心跳、超时 15 秒判故障,可以减少误判,但故障发现至少有十几秒延迟高可用不是永不故障,而是用冗余、隔离、自动切换和演练降低故障影响
健康检查与心跳 面试拆解:
1. 客户端或注册中心探测
2. 服务返回健康状态
3. 连续失败计数
4. 摘除异常实例
5. 恢复后预热加回
6. 监控误判和漏判

记忆钩子:先给结论,再拆流程,再讲数字例子和失败边界;回答「健康检查与心跳」时要围绕题目问法收束,不要把相邻概念堆成一段没有重点的名词清单。

  • 误区:进程存活就代表健康。 线程池打满、数据库不可用或磁盘满时,进程可能活着但业务不可用。
  • 误区:心跳越频繁越好。 频繁心跳增加负载,也可能在网络抖动时造成误判。
  • 误区:一次失败就应该摘除。 短暂抖动常见,通常要连续失败和恢复阈值。
  • 追问:健康检查分几类? 存活检查、就绪检查、业务依赖检查和深度检查。
  • 追问:如何避免雪崩式摘除? 设置最小保留实例、摘除比例上限和熔断保护。
  • 追问:恢复后为什么要预热? 避免冷缓存、冷连接和 JIT 抖动导致刚恢复又被打满。

九、加强记忆

健康检查和心跳的作用是让系统及时发现“谁不能服务”。设计时记住三层:进程是否活着,实例是否能接流量,业务链路是否真的可用。再加上连续失败阈值、恢复防抖和网络分区处理,探活机制才不会从保护系统变成制造抖动的源头。