symfony官方推荐使用symfony/health-bundle组件实现健康检查端点,它自symfony 6.2起取代已停更的symfony/health-check;需手动注册路由、配置databasecheck等服务,并注意环境适配与超时控制。

健康检查端点该用哪个 Symfony 组件
Symfony 官方推荐用 symfony/health-check(即 symfony/health-bundle 的前身),但注意:它从 Symfony 6.2 起已不再维护,当前稳定方案是使用 symfony/health-bundle。别直接装旧包,否则会遇到 Class "Symfony\Component\Health\Check\CheckInterface" not found 这类错误。
安装命令必须是:
composer require symfony/health-bundle
它依赖 symfony/framework-bundle 和 PHP 8.1+,如果你还在用 PHP 7.4 或 Symfony 5.4,得先升级或改用自定义控制器方案。
如何注册一个基础数据库连通性检查
默认安装后,symfony/health-bundle 不自动检测数据库——你得手动配置一个 DatabaseCheck 实例并注册为服务。常见坑是漏掉 database_url 配置或没传入正确的 Doctrine\DBAL\Connection。
- 确保
doctrine.dbal.url在config/packages/doctrine.yaml中已正确定义 - 在
config/services.yaml中声明检查服务:
App\Health\DatabaseCheck:
arguments: ['@doctrine.dbal.default_connection']
然后在 config/packages/health.yaml 中启用:
health:
checks:
database: 'App\Health\DatabaseCheck'
这样访问 /health 时才会真正执行 SQL SELECT 1 并返回 "status": "ok" 或 "status": "error"。
为什么 /health 返回 404 或 500
两个最常见原因:路由未导入、检查逻辑抛出未捕获异常。
-
symfony/health-bundle不自动注册路由,必须手动在config/routes/health.yaml加:
health_check:
resource: '@SymfonyHealthBundle/Resources/config/routing.xml'
- 如果自定义检查类里调用了未初始化的 service(比如
$this->entityManager为空),会直接触发 500;建议在check()方法开头加if (!$this->connection->isConnected()) { return new CheckResult(CheckResult::STATUS_CRITICAL); } - 生产环境默认禁用调试,错误不输出堆栈,查日志看
var/log/prod.log里是否出现Health check "database" failed
如何让健康检查跳过某些环境或服务
不是所有检查都该在每个环境运行。比如 Redis 检查在本地开发可能没启,硬要连会导致失败;或者你只想在 Kubernetes 的 liveness 探针中检查 DB,readiness 中额外加缓存和外部 API。
- 用条件化服务定义:在
config/services_dev.yaml中移除或注释掉 Redis 检查服务 - 为不同端点配不同检查集:新增
/health/live和/health/ready,分别绑定不同health.checks配置块 - 避免在
check()里写耗时操作(如 HTTP 请求),超时默认是 1 秒,超过会标记为timeout状态,且不重试
复杂点在于,Kubernetes 的 probe 默认只认 HTTP 状态码,而 symfony/health-bundle 对所有失败统一返回 200 + JSON body;你得配合 Nginx 或 Envoy 做状态码映射,或者自己写个轻量控制器直接 return new Response('', $result->getStatus() === 'ok' ? 200 : 503)。











