PHP健康检查:从原理到实战的完整指南
目录导读
什么是PHP健康检查?为什么重要?
PHP健康检查 是指通过自动化脚本或工具,定期检测PHP服务是否正常运行、响应是否达标、资源是否耗尽的过程,对于使用PHP构建的Web应用(如WordPress、Laravel、Symfony项目),健康检查是保障高可用性的第一道防线。

为什么需要?
- 宕机发现:PHP-FPM进程挂掉、内存泄漏导致502错误,健康检查能第一时间警报。
- 负载均衡判断:Nginx反向代理、云负载均衡器(如AWS ELB)依赖健康检查决定流量转发。
- 自动化运维:在Kubernetes、Docker Swarm等容器编排中,健康检查决定Pod的启停与重启策略。
核心问题:“PHP怎么执行健康检查?” 答案取决于你的架构——是单机PHP-FPM、多节点集群,还是容器化部署。
PHP健康检查的核心机制与工作原理
健康检查通常分为 活性检查和 就绪检查:
- 活性检查(Liveness Probe):判断PHP进程是否存活,检测PHP-FPM进程是否存在,端口是否监听(默认9000)。
- 就绪检查(Readiness Probe):判断PHP应用是否能够正常处理请求,请求一个特定的健康端点,检查数据库连接、缓存服务、磁盘空间等。
工作原理图示:
客户端/负载均衡器 → HTTP请求 /health-check.php → PHP解析 → 返回HTTP 200/503
↓
内部检测:PHP版本、扩展、数据库、磁盘、内存等
常见PHP健康检查方法详解
1 基础TCP/UDP端口检查
适用于检测PHP-FPM是否监听端口:
# Linux命令检查9000端口 netstat -anp | grep 9000 # 或使用curl模拟TCP连接 curl -v telnet://127.0.0.1:9000
局限性:端口存活不代表PHP能正常处理请求,PHP-FPM进程卡死但端口仍连接。
2 HTTP端点健康检查(最常用)
在项目中创建一个公开的健康检查文件 /health-check.php:
<?php
// 基础返回200
header("HTTP/1.1 200 OK");
echo json_encode(["status" => "healthy"]);
负载均衡器(如Nginx、HAProxy)每隔几秒访问此URL,若返回200则视为健康。
3 通过PHP-FPM状态页检查
启用PHP-FPM状态页:
# php-fpm.conf pm.status_path = /fpm-status
然后通过Nginx或直接访问查看进程状态:
curl http://127.0.0.1/fpm-status?json
返回包括 active processes、idle processes、max active processes 等关键指标。
4 容器化环境检查(Docker/Kubernetes)
使用 exec 命令检测PHP进程:
# Kubernetes Deployment配置
livenessProbe:
exec:
command:
- php
- -r
- "echo 'health'"
initialDelaySeconds: 10
periodSeconds: 5
或使用HTTP Get:
readinessProbe:
httpGet:
path: /health-check.php
port: 80
initialDelaySeconds: 5
periodSeconds: 10
手把手教你编写PHP健康检查脚本
一个生产级健康检查脚本应包含:PHP版本、扩展、数据库连接、缓存、磁盘空间、内存使用等。
示例:/var/www/html/health-check.php
<?php
$health = ['status' => 'healthy', 'checks' => []];
// 1. 检查PHP版本
if (version_compare(PHP_VERSION, '8.0', '<')) {
$health['status'] = 'degraded';
$health['checks']['php_version'] = 'Warning: PHP version '.PHP_VERSION.' is below 8.0';
} else {
$health['checks']['php_version'] = 'OK';
}
// 2. 检查关键扩展
$extensions = ['pdo_mysql', 'redis', 'json', 'mbstring'];
foreach ($extensions as $ext) {
if (!extension_loaded($ext)) {
$health['status'] = 'unhealthy';
$health['checks']["ext_$ext"] = "Missing extension: $ext";
} else {
$health['checks']["ext_$ext"] = 'OK';
}
}
// 3. 检查数据库连接(假设有MySQL)
try {
$dsn = 'mysql:host=127.0.0.1;dbname=test;charset=utf8';
$db = new PDO($dsn, 'user', 'pass', [PDO::ATTR_TIMEOUT => 3]);
$db->query('SELECT 1');
$health['checks']['database'] = 'OK';
} catch (Exception $e) {
$health['status'] = 'unhealthy';
$health['checks']['database'] = 'Failed: '.$e->getMessage();
}
// 4. 检查磁盘空间(根目录可用空间)
$disk_free = disk_free_space('/');
$disk_total = disk_total_space('/');
$disk_usage_percent = round((1 - $disk_free / $disk_total) * 100);
if ($disk_usage_percent > 90) {
$health['status'] = 'degraded';
$health['checks']['disk'] = "Warning: Disk usage at {$disk_usage_percent}%";
} else {
$health['checks']['disk'] = "OK: {$disk_usage_percent}% used";
}
// 5. 返回JSON
header('Content-Type: application/json');
if ($health['status'] === 'unhealthy') {
http_response_code(503);
} elseif ($health['status'] === 'degraded') {
http_response_code(200); // 或200表示仍可用,但记录警告
}
echo json_encode($health, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
调用方法:
curl -I http://your-server/health-check.php # 响应示例:HTTP/1.1 200 OK 或 503 Service Unavailable
集成到负载均衡与监控系统
1 Nginx负载均衡检测
upstream php_backend {
server 192.168.1.10:80;
server 192.168.1.11:80;
# 使用健康检查模块(nginx-plus 或 nginx-upsync)
# 普通nginx可配合fail_timeout
fail_timeout=10s;
}
更精确的做法:使用第三方的 nginx-upsync 模块,或配置 proxy_pass + health_check(nginx plus)。
2 HAProxy健康检查
backend php_servers
option httpchk GET /health-check.php HTTP/1.0
http-check expect status 200
server php1 192.168.1.10:80 check inter 3000 rise 2 fall 3
server php2 192.168.1.11:80 check inter 3000 rise 2 fall 3
3 云负载均衡器(如AWS ALB)
- 路径:
/health-check.php - 匹配:HTTP 200
- 间隔:30秒
- 超时:5秒
4 监控告警集成(Prometheus + Grafana)
在健康检查脚本中加入指标暴露(或使用现成的php-fpm-exporter),通过Prometheus采集数据,并在Grafana中监控PHP-FPM进程数、请求耗时、内存占用。
常见问题FAQ
Q1: PHP健康检查返回503,但网站能访问,为什么?
A: 健康检查脚本可能检测到了非致命的降级情况(如磁盘空间高、数据库连接慢),检查脚本的输出JSON,定位具体失败的检查项,也可能是PHP-FPM进程池满了,健康检查请求被拒绝,而其他请求仍在排队。
Q2: PHP-FPM的pm.status_path与自定义健康检查脚本,哪个更好?
A: 两者应配合使用。pm.status_path提供FPM内部状态,适合监控进程池;自定义健康检查脚本能检测业务级依赖(数据库、缓存),建议:pm.status_path用于容器活性探针,自定义脚本用于就绪探针。
Q3: 健康检查脚本应该放在哪里?
A: 最佳实践:放在Web根目录下的独立子目录(如/health/),并通过Nginx限制IP访问(只允许内网或负载均衡器IP),避免暴露健康信息给公网。
Q4: 健康检查频率设置多少合适?
A:
- 负载均衡:每3-10秒一次(根据业务敏感度)。
- Kubernetes: Liveness 5-15秒,Readiness 10-30秒。
- 过短的间隔会增大服务器压力,建议在检查脚本中避免复杂数据库查询。
Q5: “PHP怎么进行健康检查”对性能有影响吗?
A: 设计得当的健康检查脚本影响极小,应避免循环、大量数据库查询、文件I/O,使用简单逻辑(如连接数据库后立即关闭,使用SELECT 1),如果站点流量极大,可将健康检查结果缓存几秒。
延伸思考: 如果你的PHP应用是API服务或需要高并发支持,建议使用 Swoole 或 Workerman 替代传统PHP-FPM,它们的健康检查机制更接近Node.js——自带内部状态统计和心跳检测,PHP健康检查”将变为对Worker进程池和协程状态的检查。
通过本文,你应该已经掌握从基础到进阶的多种PHP健康检查方法,下一步是结合你的具体架构(单机、集群、容器化)选择最合适的方案,并集成到持续监控系统中。