应使用 symfony/health-check-bundle,它轻量、活跃维护、兼容 Symfony 5.4+ 及 6.x/7.x,自动启用,默认路由 /health 返回 200 OK + {"status": "ok"}。

健康检查接口该用哪个Bundle
Symfony官方不提供开箱即用的健康检查端点,symfony/health-check-bundle 是目前最轻量、维护活跃且兼容 Symfony 5.4+ 和 6.x/7.x 的选择。它不依赖 Doctrine 或其他重型组件,适合只检查 HTTP 可达性、Redis 连通性或自定义逻辑的场景。
避免使用已归档的 liip/monitor-bundle(PHP 8+ 兼容性差)或过度复杂的 spatie/laravel-health(Laravel 专用,非 Symfony)。
- 执行
composer require symfony/health-check-bundle - Bundle 会自动启用(Symfony Flex ≥1.4),无需手动注册
- 默认路由为
/health,返回200 OK+ JSON{"status": "ok"}
如何添加数据库连通性检测
单纯返回 200 没意义,真实环境需验证关键依赖是否就绪。Bundle 提供 DatabaseHealthCheck,但默认不启用 —— 它需要你显式配置并注入 Doctrine\DBAL\Connection 实例。
在 config/packages/health_check.yaml 中添加:
health_check:
checks:
database:
type: 'database'
options:
connection: 'doctrine.dbal.default_connection'
注意:connection 值必须与你的 Doctrine 配置中定义的连接名一致(常见为 default_connection,而非 default)。若用多数据库,此处填具体连接 ID。
- 失败时返回
503 Service Unavailable,响应体含"error": "Connection failed" - 该检查仅执行
PDO::query("SELECT 1"),不触发任何 ORM 逻辑,开销极低 - 若 Doctrine 未启用或连接配置错误,启动时会抛出
InvalidArgumentException
怎么加入自定义健康逻辑(如外部API可达性)
用 AbstractHealthCheck 写一个服务类,比硬编码判断更易测试和复用。例如检查第三方支付网关是否响应:
namespace App\Health;
<p>use Symfony\Component\Health\Check\AbstractHealthCheck;
use Symfony\Contracts\HttpClient\HttpClientInterface;</p><p>class PaymentGatewayHealthCheck extends AbstractHealthCheck
{
public function __construct(private HttpClientInterface $httpClient) {}</p><pre class="brush:php;toolbar:false;">protected function doCheck(): ?string
{
try {
$response = $this->httpClient->request('GET', 'https://api.pay.example.com/health', [
'timeout' => 2.0,
]);
if ($response->getStatusCode() !== 200) {
return sprintf('Bad status: %d', $response->getStatusCode());
}
} catch (\Exception $e) {
return $e->getMessage();
}
return null; // 表示通过
}}
然后在配置中注册:
health_check:
checks:
payment_gateway:
type: 'custom'
class: 'App\Health\PaymentGatewayHealthCheck'
- 返回
null表示健康;返回字符串表示不健康,内容将作为error字段输出 - 不要在
doCheck()中做耗时操作(如重试、长轮询),超时默认 5 秒,可配timeout参数 - 该服务会被自动标记为
public和autoconfigure,无需额外设tags
为什么 /health 接口返回 404 或权限拒绝
两个高频原因:路由未加载,或安全配置拦截了未认证访问。
检查 config/routes/health_check.yaml 是否存在且内容为:
health_check:
resource: '@HealthCheckBundle/Resources/config/routing.yaml'
若项目启用了 security.yaml 的全局访问控制(如 access_control 中匹配 ^/),必须显式放行:
access_control:
- { path: ^/health, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- 别用
roles: PUBLIC_ACCESS(Symfony 6.2+ 已弃用) - 若部署在反向代理后(如 Nginx),确保
X-Forwarded-For头未被过滤,否则健康探针可能被误判为非法请求 - 本地开发用
bin/console debug:router | grep health确认路由是否注册成功
健康检查不是“加个接口就完事”,真正难的是判断哪些依赖值得检查、超时设多长、失败后是否要降级响应——这些都得贴着你的部署拓扑和 SLO 来调。











