如何配置K8s存活与就绪探针 让Spring Boot高负载下不被重启
核心认知澄清
首先要明确:临时让Liveness探针返回失败、模拟未启动状态的操作,会直接触发K8s的Pod重启流程,完全违背你“避免Pod被意外重启”的核心目标。Liveness探针的判定逻辑是“连续探测失败即代表进程已失去自主运行能力,需要重启恢复”,不存在“K8s会因为探针返回未就绪状态就跳过重启”的机制,这个方向从逻辑上就走不通。
可落地的分层实现方案
1. 严格拆分两类探针的职责边界
这是Spring Boot + Kubernetes场景下的原生能力,不需要额外写自定义逻辑就能落地:
- Liveness探针:只用于检测应用进程是否处于“可自主运行、无永久不可逆故障”的状态,绝对不能把请求队列长度、线程池使用率这类临时高负载的指标纳入判定范围。
直接使用Spring Boot Actuator 2.3+原生提供的/actuator/health/liveness端点作为Liveness探针的检测路径即可,这个端点的默认实现只会识别会导致应用永久卡死的故障(比如关键Bean初始化失败、核心依赖连接永久中断),不会把临时高负载判定为不健康状态。 - Readiness探针:专门承接“应用当前是否适合接收新流量”的判定,对应Actuator原生的
/actuator/health/readiness端点。你可以通过自定义健康指标的方式,把以下高负载场景纳入Readiness的判定维度:- 服务器工作线程池的排队队列长度超过预设阈值
- 线程池活跃线程数达到最大容量的90%以上
- 接口平均响应时间超过可接受范围
当这些指标触发时,Readiness探针返回OUT_OF_SERVICE状态,K8s就会自动将这个Pod从Service的负载均衡后端列表中移除,暂停向其转发新请求,让应用有充足资源处理完已经接收到的队列内请求。整个过程完全不会触发Pod重启,只是临时停止新流量流入。
2. 配套Actuator端口的独立配置
你提到的management.server.port=8081是必须落地的基础配置,绝大多数高负载下的探针误判问题都源于没有拆分端口:
- 当应用业务线程池耗尽时,所有走业务端口的请求都会进入排队状态,但独立端口运行的Actuator探测端点不受业务线程池队列的影响,不会出现“探针请求自己都排队超时,被K8s误判为进程卡死”的问题。
- 注意要对K8s探针的访问路径做全量放通,不要给Actuator端点配置登录鉴权、流量限速规则,避免探针本身因为应用负载升高出现访问超时。
3. 和HPA的协同配置逻辑
你提到的HPA不是替代探针方案的手段,是作为流量削峰的配套能力存在的:
- 当集群中多个Pod的Readiness探针都因为高负载返回不可用状态时,HPA可以基于CPU、内存、自定义线程池队列长度等指标自动扩容新的Pod,承接溢出的流量。
- 不要将HPA的扩容触发逻辑绑定到Liveness探针的状态上,扩容判断要从Readiness端点暴露的指标、Prometheus采集的应用层指标获取,避免因为Pod不必要的重启触发无效扩容。
高负载状态下的状态自主管控实现
你设想的“应用自主管控运行状态、避免Pod被误杀”的需求,完全可以通过Actuator的健康分组机制实现,不需要去干预Liveness探针的逻辑:
- 将所有和高负载相关的检测指标全部划入Readiness对应的健康分组,当应用负载升高、队列变长时,自动将Readiness状态切回
OUT_OF_SERVICE,等待负载回落到阈值以内后,再自动将状态切回UP,K8s会自动将Pod重新加回负载均衡的后端列表。 - 严禁任何主动修改Liveness端点返回值的操作,哪怕只是临时想模拟服务启动的未就绪状态,只要Liveness返回非200状态,K8s就会立刻发起Pod重启流程,完全无法实现你“自主管控状态、避免重启”的目标。
内容的提问来源于stack exchange,提问作者J.J. Beam
相关产品推荐
相关产品推荐

