容器频繁重启多因健康探针误判,核心是延长initialdelayseconds(45–90s)或start_period(40–60s),设timeoutseconds/timeout为5–10秒、failurethreshold/retries为3,并确保/health端点轻量、分离liveness与readiness职责。
容器频繁重启,十有八九是健康探针在“误判”——不是应用真挂了,而是探针太急、太严、太 impatient。核心思路就一条:让探针等得起、忍得住、判得准。
延长启动宽限期(start-period / initialDelaySeconds)
很多应用冷启动要花十几秒甚至更久(比如 Spring Boot 加载上下文、数据库连接池初始化、缓存预热),但默认的健康检查一启动就开测,必然失败。必须给足“喘息时间”:
- Docker / Docker Compose 中设 start_period: 40s~60s(慢启动服务建议 ≥60s)
- Kubernetes 中设 initialDelaySeconds: 45~90(覆盖完整初始化周期)
- 这个阶段内,无论检查结果如何,Docker 或 kubelet 都不会标记为 unhealthy,也不会触发重启
调高超时与重试容错(timeoutSeconds / timeout + retries)
网络抖动、GC 暂停、瞬时高负载都可能导致单次探测延迟。把超时设成 1 秒或 3 秒,等于主动邀请误杀:
- timeoutSeconds(K8s)或 timeout(Docker)建议设为 5~10 秒——足够响应,又不至于无限等待
- failureThreshold(K8s)或 retries(Docker)固定设为 3——允许偶发失败,避免一次超时就判死刑
- 避免用默认 timeout=1s 或 retries=1,这是高频误重启的头号配置雷区
确保健康端点轻量且稳定
如果 /health 接口本身要查数据库、调远程服务、加载大文件,那它就成了故障放大器:
- 实现专用的 /health 或 /ready 端点,只检查进程存活、监听端口、内存基本可用等本地状态
- 绝对不要在健康检查里连 MySQL、Redis 或调用其他微服务
- 返回内容极简(如 HTTP 200 + “OK”),响应时间控制在毫秒级
区分 Liveness 和 Readiness,各司其职
混用两个探针是常见误区。它们目标不同,配置逻辑也应分离:
- Liveness:只管“还活着吗?”——失败就重启。可稍宽松(如 initialDelaySeconds 更长、failureThreshold=3)
- Readiness:只管“能接流量吗?”——失败就摘流量,不重启。可更灵敏(如 periodSeconds=5s),但同样要设好 timeout 和 start-period
- 切忌把 Readiness 配成和 Liveness 一样严,否则流量还没导进去就被踢出服务列表











