2. 健康检查基础:什么是健康检查,为什么需要
2.1 健康检查的本质
健康检查,说白了就是定期给服务“把脉”。
你向一个密码接口发一个探测请求,看它能不能正常返回。能,就标记为“健康”;不能,就标记为“异常”。
我刚开始做接口网关时,总觉得这步是多余的——服务不就在那里跑着吗?后来有一次,密码机内存泄漏,接口返回超时,但请求还是被继续转发进去,导致大量加密任务卡死……嗯,从那以后,我再也不跳过健康检查了。
核心定义:健康检查 = 定期探测 + 状态判定 + 自动摘除异常节点。
2.2 为什么密码接口必须做健康检查
密码接口跟普通业务接口不太一样。它处理敏感数据,一旦故障,影响面很大。
- 避免雪崩:一个节点挂了,如果还不摘掉,后续请求全堵在那儿,连接池撑爆,整个集群都可能被拖垮。
- 保证高可用:密码服务通常是 7×24 的,不能等人发现故障再手动切。健康检查让故障转移自动完成。
- 合规要求:很多金融、政务场景要求接口必须支持健康检查,作为运维审计的一部分。
- 降低误报:你以为接口正常,其实它已经在返回错误码了。健康检查能提前发现“亚健康”状态。
我个人习惯把健康检查放在网关层。这样所有密码接口共享一套检测逻辑,改起来也方便。
2.3 常见的健康检查类型
| 类型 | 原理 | 适用场景 | 缺点 |
|---|---|---|---|
| 主动探测 | 网关定时发 HTTP/TCP 心跳到 /health 端点 | 密码接口有独立健康端点 | 增加少量网络开销 |
| 被动检查 | 监控真实请求的失败率和响应时间 | 不想增加额外请求 | 发现故障有延迟 |
| 心跳包 | 后台服务自己定时上报状态 | 长连接场景(如加密通道) | 需要服务端配合改造 |
我在项目中最常用的是 主动探测 + 被动回退。主动探测每 5 秒发一次,如果连续 3 次失败就摘除。同时监控真实请求的失败率,一旦突然飙升,也立刻触发检查——防止主动探测本身出问题。
2.4 一个简单的健康检查代码示例(Python)
下面是一个极简的主动探测函数。你想想看,核心逻辑其实就这几行:
import requests
import time
def check_health(url, timeout=2):
try:
resp = requests.get(url, timeout=timeout)
if resp.status_code == 200 and resp.json().get("status") == "ok":
return True
except (requests.ConnectionError, requests.Timeout):
pass
return False
# 循环探测
while True:
alive = check_health("http://crypto-svc-1:8080/health")
print(f"节点状态: {'健康' if alive else '异常'}")
time.sleep(5)
小技巧:健康检查的端点最好返回{"status":"ok"}这样的固定格式,不要带业务数据。我踩过坑:Health API 里塞了数据库查询,结果数据库慢导致健康检查自己超时——误判了。
2.5 健康检查的常见陷阱
避坑指南:
- 别只检查端口存活(TCP 通不代表业务正常)。我遇到过 TCP 握手成功,但业务进程僵死的情况。
- 超时时间别设太长。我曾经设了 10 秒超时,结果健康检查线程被卡住,挤占了正常请求连接。建议 1-2 秒。
- 健康检查的日志要单独归档。不然排查问题时,健康检查日志淹没在业务日志里,很难找。
记得有一次,我把健康检查的失败阈值设得太小,网络抖动时频繁摘除节点,导致故障转移来回切换。后来加上“连续 N 次失败才算真异常”的滑动窗口,就稳定多了。