别把探活当就绪:三种健康检查怎么拆
探活接口返回 200,不代表实例可以接流量。把启动、存活、就绪混成一个 URL,是上线后最常见的误伤:进程还在拉配置就被杀掉,或者下游一抖,整组实例一起被摘流。
一次请求进来之前,平台其实在问三个不同的问题。
启动检查:初始化结束了没有
镜像拉取之后的配置解密、连接池预热、本地缓存装载,都应该放在启动检查里。它失败时的动作是继续等,而不是重启。如果启动检查里夹了「下游必须可用」,一次依赖抖动就会把正在启动的实例反复打回原点。启动可以给到几十秒甚至更长,并允许连续失败。
存活检查:进程是不是已经没救了
死锁、事件循环卡死、无法再接受任何连接,才应该让存活检查失败。它失败的代价是重启,所以判据要窄:只看本进程是否还能工作,不要把缓存超时、下游 5xx 算进来。外部依赖挂了就重启自己,只会放大故障。存活间隔可以短,但失败阈值要放宽,避免一次 GC 停顿就被判死。
就绪检查:现在能不能接新流量
连接池耗尽、正在优雅退出、本地队列超过阈值、关键配置还没刷到,都应该让就绪失败,让负载均衡把新请求送去其他实例。已经在处理的请求不要被存活检查误杀。就绪失败的动作是摘流,不是重启。就绪可以更灵敏,失败一两次就摘流,恢复后立刻加回。
还有一个容易忽略的点:就绪检查不要同步调用慢接口。如果检查本身把线程打满,实例看起来不健康,其实是被检查拖垮的。就绪路径只读本地状态:连接是否建立、熔断器是否打开、是否处于 draining。
上线前用三句话自测。初始化没完成时,新请求会不会进来?进程死锁时,平台会不会重启,而不是一直摘流?下游抖动时,是摘掉本实例的新流量,还是把整组实例一起重启?三个答案分别对应就绪、存活、启动。对上了,再考虑要不要合并成一个接口。
- 点赞
- 收藏
- 关注作者
评论(0)