Hyperf服务K8s健康检查失败主因是/health端点未启用或暴露:默认不注册health组件、未配置路由、探针端口不匹配、启动耗时未适配参数、liveness与readiness混用。

Hyperf 服务在 Kubernetes 中健康检查失败,大概率不是代码问题,而是 /health 端点被默认禁用或未正确暴露 —— 这是 80% 的 Hyperf 用户踩的第一个坑。
Hyperf 默认不启用 health 组件
Hyperf 官方的 hyperf/health-check 组件默认不自动注册、不监听任何路由,即使你安装了包,GET /health 也会直接返回 404。Kubernetes 的 livenessProbe 发起 HTTP 请求时自然失败。
- 确认是否已执行
composer require hyperf/health-check - 检查
config/autoload/dependencies.php中是否注册了Hyperf\HealthCheck\Checker\TcpChecker::class或其他 checker(非必须,但需有至少一个) - 最关键:检查
config/autoload/routes.php是否显式定义了 health 路由 —— 默认没有
正确做法是在路由文件中加一行:
Router::get('/health', function () {
return 'ok';
});或者更规范地使用组件内置逻辑(推荐):
Router::addRoute(['GET'], '/health', [\Hyperf\HealthCheck\HealthCheckController::class, 'index']);
HTTP 探针路径与端口必须匹配容器实际监听配置
Hyperf 默认监听 0.0.0.0:9501,但很多用户在 server.php 或启动命令里改了端口(比如 9502),却忘了同步更新 livenessProbe.httpGet.port。
-
livenessProbe.httpGet.port必须等于容器内进程实际绑定的端口,不能是 Service 的 targetPort 或 NodePort - 如果用了
env变量注入端口(如${HTTP_PORT}),确保 Deployment 中该 env 已正确定义且值一致 - 验证方式:进容器执行
ss -tlnp | grep :9501,确认监听地址和端口
错误示例(端口不一致):
livenessProbe:
httpGet:
path: /health
port: 8080 # ❌ 容器实际监听 9501,这里写 8080 必然超时探针参数没适配 Hyperf 启动耗时
Hyperf 基于 Swoole,冷启动加载配置、注解、协程池等可能需要 3–8 秒;若 initialDelaySeconds 设为 5,而首次请求恰好卡在扫描注解阶段,就可能失败并触发重启循环。
-
initialDelaySeconds建议设为15起步,观察日志后逐步下调 -
timeoutSeconds至少设为3(Swoole 首次响应略慢),低于 2 秒容易误判 -
failureThreshold别设成1,网络抖动或 GC 暂停都可能导致单次失败,设3更稳妥
典型安全配置:
livenessProbe:
httpGet:
path: /health
port: 9501
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3别把 readiness 和 liveness 混用同一个端点
很多用户图省事,livenessProbe 和 readinessProbe 全指向 /health。但 Hyperf 的 /health 默认只检查进程存活,不检查 DB 连接、Redis 可用性等业务依赖 —— 这会导致 readiness 失效,流量照常打进来,结果请求报错。
- 建议分离:liveness 用轻量
/health(仅确认 Swoole Worker 存活),readiness 用/ready并集成 DB/Redis 检查逻辑 - Hyperf 的
health-check组件支持多 checker,可在config/autoload/health.php中配置DbChecker、RedisChecker等,并绑定到不同路由 - 如果业务允许“启动即就绪”,那 readiness 可复用 /health;但只要涉及外部依赖,就必须分层
复杂点在于:Hyperf 的 checker 默认是同步阻塞执行的,若 DB 检查超时,整个 readiness 请求就会卡住 —— 这反而会拖垮探针,所以务必给每个 checker 设置合理的 timeout 参数(例如 DB 连接超时设为 2 秒以内)。


















