本文目录导读:

- 最简单:返回固定响应的 HTTP 端点
- 中级:检查关键依赖是否正常(数据库、Redis 等)
- 高级:PHP-FPM 进程存活检查(针对容器)
- 针对 CLI 脚本 / 常驻进程的存活检查
- 在 Dockerfile 或 docker-compose 中集成
- 最佳实践总结
- 常见问题
在 PHP 中,“存活检查”(Health Check / Liveness Probe)通常用于监控一个 PHP 服务(Web 应用、API 服务或后台进程)是否正常运行,常见的场景包括:
- Docker / Kubernetes 容器探针:检查容器里的 PHP-FPM 或 PHP 进程是否还活着。
- 负载均衡器:检查后端 PHP 服务器是否还能正常处理请求。
- 监控系统:Prometheus、Nagios 等定期检查服务是否健康。
以下是几种常用的 PHP 存活检查方法,从简单到复杂:
最简单:返回固定响应的 HTTP 端点
这是最常用的方法,创建一个无需数据库、无需外部依赖的简单 PHP 文件,直接返回 200 OK。
文件:/healthcheck.php
<?php
// 设置响应头
header('HTTP/1.1 200 OK');
header('Content-Type: application/json');
echo json_encode(['status' => 'ok', 'timestamp' => time()]);
exit;
检查方式:
curl http://your-php-server/healthcheck.php
# 期望输出:{"status":"ok","timestamp":1620000000}
在 Docker / Kubernetes 中使用:
# livenessProbe
livenessProbe:
httpGet:
path: /healthcheck.php
port: 80
initialDelaySeconds: 10
periodSeconds: 5
中级:检查关键依赖是否正常(数据库、Redis 等)
如果你的应用依赖数据库或缓存,存活检查可以顺便验证这些依赖是否可用,但要注意:不要让存活检查太重(否则可能引起雪崩)。
文件:/healthcheck.php
<?php
$status = 'ok';
$checks = [
'database' => false,
'redis' => false,
];
// 检查 MySQL
try {
$pdo = new PDO('mysql:host=127.0.0.1;dbname=test;charset=utf8', 'user', 'pass', [
PDO::ATTR_TIMEOUT => 3
]);
$pdo->query('SELECT 1');
$checks['database'] = true;
} catch (Exception $e) {
$status = 'degraded';
// 记录日志,但不要直接退出
}
// 检查 Redis
try {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379, 3);
$redis->ping();
$checks['redis'] = true;
} catch (Exception $e) {
$status = 'degraded';
}
// 如果关键依赖挂了,可以返回 503
if ($status !== 'ok') {
http_response_code(503); // Service Unavailable
}
header('Content-Type: application/json');
echo json_encode([
'status' => $status,
'checks' => $checks,
'timestamp' => time()
]);
注意:
- 连接数据库和 Redis 时设置超时(避免阻塞太久)
- 不建议在存活检查中执行复杂的 SQL 或业务逻辑
- 如果依赖完全不可用,可以返回
503,负载均衡器就会踢掉该节点
高级:PHP-FPM 进程存活检查(针对容器)
如果你的 PHP 应用是通过 PHP-FPM 运行的(Nginx + PHP-FPM),可以直接检查 PHP-FPM 的进程或端口是否存活。
方法 A:检查 PHP-FPM 端口
# 默认端口是 9000,也可能是 9001 等 curl -s --connect-timeout 3 http://127.0.0.1:9000/ping
在 PHP-FPM 配置中启用 ping:
编辑 php-fpm.conf 或 pool.d/www.conf:
pm.status_path = /status ping.path = /ping ping.response = pong
然后重启 PHP-FPM,检查:
curl http://127.0.0.1:9000/ping # 期望输出:pong
方法 B:检查进程数
# 检查 PHP-FPM 进程是否存在 pgrep php-fpm | wc -l # 如果大于 0 说明存活
方法 C:使用 sock 文件(Unix socket)
PHP-FPM 监听的是 socket(/var/run/php-fpm.sock):
# 检查 socket 文件是否存在 ls -la /var/run/php-fpm.sock &> /dev/null && echo "OK" || echo "DEAD"
针对 CLI 脚本 / 常驻进程的存活检查
对于后台运行的 PHP 脚本(比如队列消费者、定时任务),可以用 PID 文件或进程名检查。
示例:
// 在脚本启动时写入 PID
file_put_contents('/tmp/myprocess.pid', getmypid());
// 存活检查脚本
$pid = file_get_contents('/tmp/myprocess.pid');
if ($pid && posix_getpgid($pid)) {
echo "Process running\n";
exit(0);
} else {
echo "Process dead\n";
exit(1);
}
或者直接检查进程名:
ps aux | grep "myprocess.php" | grep -v grep | wc -l
在 Dockerfile 或 docker-compose 中集成
示例 Dockerfile:
FROM php:8.2-fpm COPY . /var/www/html RUN echo '<?php echo "ok";' > /var/www/html/healthcheck.php HEALTHCHECK --interval=10s --timeout=3s \ CMD curl -f http://localhost/healthcheck.php || exit 1
docker-compose 示例:
services:
php:
image: your-php-app
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/healthcheck.php"]
interval: 10s
timeout: 3s
retries: 3
最佳实践总结
| 场景 | 推荐方法 | 注意事项 |
|---|---|---|
| Docker / Kubernetes 探针 | HTTP 端点 healthcheck.php 返回 200 |
不要依赖数据库,避免探针太慢 |
| 数据库依赖检查 | 在探针中轻量连接 DB,超时 2-3 秒 | 返回适当的 HTTP 状态码(200/503) |
| PHP-FPM 检查 | 使用 PHP-FPM 内置的 ping 或 port check | 确认端口或 socket 是否暴露 |
| 后台进程检查 | PID 文件 + 定期检查 | 避免僵尸进程 |
| 高可用 + 严格 | 返回 JSON 包含状态码 + 依赖健康详情 | 配合监控系统告警 |
常见问题
Q: 存活检查返回 200 但应用实际挂了?
A: 存活检查只检查了 PHP 进程是否在运行,没检查业务逻辑是否正确,可以增加 就绪检查(Readiness Probe) 来验证业务是否可用(比如能正常渲染一个页面)。
Q: 探针时间设置多少合适?
- HTTP 超时:3-5 秒
- 间隔:5-15 秒
- 初始延迟:根据应用启动时间,一般 10-30 秒
Q: 存活检查需要验证登录吗?
不需要,存活检查应该无状态、无认证,否则探针会失败并被误认为服务挂了。