开始前,会这些就够了
- 知道服务会接收请求,数据库可能暂时不可用;示例只需能运行 Python
一个服务的健康页一直返回 200,用户提交表单却总失败,可能并不矛盾:健康页只证明它检查的那一小段成功了。若它只回一行固定文字,就没有证明表单能写进数据库。
探针是定期替系统问一个小问题的检查。问题问得不同,失败后的动作也应不同;不能把所有异常都归为“赶快重启”。
先看这一页究竟检查了什么
Kubernetes 的 HTTP 探针按收到的状态码判断,成功范围是大于等于 200、且小于 400。通过这项检查,只表示满足该探针的约定,不是替全部业务盖章。
还要核对健康页经过哪条路。Spring Boot 文档提醒:若管理接口和业务接口使用不同端口与处理组件,管理页可用时,业务侧仍可能接不了连接。因此应同时观察用户真正需要的业务结果。
三个检查,分别决定不同事情
startup 问“启动准备做好了吗”。配置它之后,启动检查尚未成功时,不执行 liveness 和 readiness 检查。启动成功后,它完成自己的任务,不会一直替代后两者。
liveness 问实例本身是否还能继续工作。连续失败达到配置门槛后,会触发容器终止,并按重启策略处理。
readiness 问现在是否适合接收流量。检查失败后,负责分配常规流量的 Service 会避开未就绪实例;这项失败本身不要求重启。
用五张状态卡拆开判断
下面主动约定:启动已通过、实例自身正常,而且数据库可用或业务允许不用数据库,才算就绪。local_ok 是预先给定的“自身能继续工作”,不是只看进程存在;db_required=False 则表示已经另有可接受的处理方式。
函数只读取布尔值。waiting 表示启动尚未通过,finished 表示先前已通过;not-run 表示另外两类检查暂不运行。它没有计时、发 HTTP 请求、累计失败次数或执行重启,也没有模拟 Kubernetes 的完整流程。
def assess(startup_passed, local_ok, db_ok, db_required):
flags = (startup_passed, local_ok, db_ok, db_required)
if any(type(value) is not bool for value in flags):
raise ValueError("all state flags must be bool")
# Assume all three probes are configured. This is not a scheduler.
if not startup_passed:
return ("waiting", "not-run", "not-run")
ready = local_ok and (db_ok or not db_required)
return (
"finished",
"pass" if local_ok else "fail",
"pass" if ready else "fail",
)
def main():
cases = [
("starting", False, True, True, True),
("normal", True, True, True, True),
("database-down", True, True, False, True),
("usable-fallback", True, True, False, False),
("local-stuck", True, False, True, True),
]
print("scenario | startup | liveness | readiness")
for name, *flags in cases:
print(" | ".join((name, *assess(*flags))))
if __name__ == "__main__":
main()
怎样运行:Python 3.10+ 标准库;保存为 probe_states.py,运行 python probe_states.py。只计算虚构状态,不需要 Kubernetes、Spring Boot 或联网。
运行后对照结果
scenario | startup | liveness | readiness
starting | waiting | not-run | not-run
normal | finished | pass | pass
database-down | finished | pass | fail
usable-fallback | finished | pass | pass
local-stuck | finished | fail | fail
记住这三点
- 健康页成功,只能说明它实际检查到的范围。
- 启动、存活和就绪对应不同问题;就绪失败本身不等于应该重启。
- 共享依赖故障应结合业务可用范围判断,别让所有实例同时无效重启。
别把例子用过头
- 本例是手写判断表,不包含探针周期、超时、失败阈值、重启策略或控制器传播时序。
- 允许不依赖数据库的分支,是已经存在可接受处理方式的假设,不会自动让写入业务变得可用。
- 就绪状态与业务结果仍需持续观察,一次通过不保证后面的每个请求都成功。
自己试一小步
一个服务既提供本地帮助页,又提交必须落库的申请,数据库暂时断开时该怎样设计检查?
- 先列出哪些能力仍可用、哪些已经无法完成,并写清用户是否接受这种限制。
- 分别写出启动、存活与就绪需要的证据,不先从状态码开始猜。
- 再考虑多个实例共用同一数据库时,全部退出流量或一起重启各会造成什么。
做到这些,就算完成
- 没有把一个固定 200 当成完整业务验证。
- 能说清判断针对实例自身还是外部依赖。
- 把自己的取舍与 Kubernetes 实际触发动作所需的配置、时序分开。
查原始资料
想确认一个细节,先看这份资料对应的部分,不必从头读完所有文档。
- Kubernetes:Liveness, Readiness, and Startup Probes (新标签页)↗
三种探针的用途、startup 成功前的抑制、HTTP 200≤状态码<400,以及失败阈值和就绪失败后的处理。
- Spring Boot:Endpoints / Kubernetes Probes (新标签页)↗
探针分组默认范围、独立管理端口的局限,以及 liveness 避免外部依赖、readiness 权衡必需依赖和共享故障。
找一份资料继续练
先选一项,按下面的范围继续学;不必从头读完整门课程。
Spring Boot:先停接新请求,再完成手头工作 (新标签页)↗
从 Actuator 的 Probes 小节区分活着与能接单,并检查管理端口是否代表业务端口。
查看学习准备与访问说明 →Kubernetes 中文:三种健康检查各自决定什么 (新标签页)↗
只比较三种探针的处理动作和连续失败阈值,记录 Ready 与重启次数所表达的不同事实。
查看学习准备与访问说明 →