本文目录导读:

- 核心思路:监控 + 检测 + 通知
- 方案一:外部监控服务(最推荐,零代码,最稳定)
- 方案二:自建监控脚本 + 定时任务(低成本,依赖自身服务)
- 方案三:高级应用性能监控(APM)+ 系统级监控(企业级)
- 关键告警通道配置(优先级从高到低)
- 最佳实践建议
- 总结:最小可行方案(30分钟内搭好)
针对PHP项目服务宕机的及时告警通知,可以构建一个多层级、多通道的告警体系,以下是几种从简单到复杂的实现方案,你可以根据团队规模和技术栈选择:
核心思路:监控 + 检测 + 通知
- 监控:检测服务是否存活(网络层面、应用层面)。
- 判断:确定是“真的宕机”还是“网络抖动”。
- 通知:通过最直接的方式触达值班人员。
外部监控服务(最推荐,零代码,最稳定)
利用第三方服务从外部监测你的服务,这是最可靠的方式,因为它不依赖于你服务器自身的稳定性。
- 推荐工具:
- UptimeRobot (免费版支持50个监控器,5分钟间隔)
- Pingdom (功能更强大,有较长的免费试用期)
- StatusCake (免费版功能不错)
- Better Uptime (集成告警和状态页面)
- 配置步骤:
- 注册并添加你的PHP网站URL。
- 设置检测频率(如5分钟/次)。
- 关键:配置告警通道:
- 电话告警(最紧急,很多付费服务支持)
- 短信告警
- 邮件告警
- Slack / 钉钉 / 飞书 / 企业微信机器人(Webhook)
- 优点:无需维护,永远在线(如你服务器断电,只有它能检测到),配置简单。
自建监控脚本 + 定时任务(低成本,依赖自身服务)
如果不想用第三方,可以在另一台独立的监控服务器(或同服务器但用不同进程)上跑脚本。
核心Shell脚本 (check_php_alive.sh)
#!/bin/bash
# 配置参数
URL="https://yourdomain.com/health_check.php" # 需要你创建一个专门用于健康检查的PHP文件
EXPECTED="OK" # 在health_check.php中return 'OK';
LOG_FILE="/var/log/php_alive.log"
NOTIFY_SCRIPT="php /path/to/notify.php" # 告警通知脚本
# 第1步:检测HTTP状态码
HTTP_CODE=$(curl -o /dev/null -s -w "%{http_code}" --connect-timeout 10 --max-time 15 "$URL")
# 第2步:检测返回内容
RESPONSE_BODY=$(curl -s --connect-timeout 10 --max-time 15 "$URL")
# 第3步:判定
if [ "$HTTP_CODE" != "200" ] || [ "$RESPONSE_BODY" != "$EXPECTED" ]; then
echo "$(date +'%Y-%m-%d %H:%M:%S') - ALERT: Service Down! HTTP: $HTTP_CODE, Body: $RESPONSE_BODY" >> "$LOG_FILE"
# 触发告警
SERVER_INFO=$(hostname -I | awk '{print $1}')
ERROR_MSG="【紧急】PHP服务器 $SERVER_INFO 宕机!HTTP状态码:$HTTP_CODE,期望:200,内容:$RESPONSE_BODY"
eval "$NOTIFY_SCRIPT" "$ERROR_MSG"
else
echo "$(date +'%Y-%m-%d %H:%M:%S') - OK: Service is up." >> "$LOG_FILE"
fi
健康检查PHP文件 (health_check.php)
放在你的项目根目录:
<?php
// 在此检查关键依赖:数据库连接、Redis、磁盘空间等
try {
// 检查数据库
$db = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'user', 'pass');
$db->query('SELECT 1');
// 检查Redis (可选)
// $redis = new Redis();
// $redis->connect('127.0.0.1', 6379);
} catch (Exception $e) {
http_response_code(500);
echo 'FAIL: ' . $e->getMessage();
exit;
}
http_response_code(200);
echo 'OK'; // 与脚本中的 EXPECTED 一致
告警通知脚本 (notify.php)
根据你选的通道编写,这里以钉钉/企微机器人为例:
<?php
if ($argc < 2) {
die("Usage: php notify.php <message>\n");
}
$message = $argv[1];
// ---- 钉钉机器人 ----
$webhook = "https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN";
$data = [
'msgtype' => 'text',
'text' => ['content' => $message]
];
$options = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\n",
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
file_get_contents($webhook, false, $context);
// ---- 企业微信机器人 ----
// $webhook = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY";
echo "Notification sent.\n";
设置定时任务 (Crontab)
# 每分钟执行一次检查 * * * * * /bin/bash /path/to/check_php_alive.sh # 或每5分钟 */5 * * * * /bin/bash /path/to/check_php_alive.sh
高级应用性能监控(APM)+ 系统级监控(企业级)
对于生产环境,建议使用专业的APM和基础设施监控工具,它们能提供更细粒度的告警(如慢查询、高内存、假死等)。
-
Prometheus + Grafana + Alertmanager:
- 采集PHP-FPM状态、Nginx日志、系统资源。
- 配置告警规则(如
php-fpm进程数 > 80%,5分钟内502错误率 > 5%)。 - Alertmanager 支持钉钉、邮件、PagerDuty。
-
Sentry:专门捕获PHP异常和错误,当出现致命错误(E_ERROR)时,可以配置Webhook触发告警。
-
New Relic / Datadog:一体化APM,检测到应用Down后直接发告警。
关键告警通道配置(优先级从高到低)
-
电话(Phone Call):你睡觉时唯一能叫醒你的方式,推荐使用:
- Twilio (需编程)
- Server酱 (微信推送 + 电话回拨)
- 云片、阿里云短信/语音 (付费)
- PagerDuty / Opsgenie (企业级,自动轮值、电话告警)
-
IM软件机器人 (钉钉/飞书/企微/Slack):最实用,能快速看到错误详情。
-
短信:比电话成本低,但易被忽略。
-
邮件:最弱,经常被塞进垃圾箱或延迟。
最佳实践建议
-
避免“告警风暴”:
- 重试机制:检查宕机时,连续失败3次(间隔10秒)才发告警,避免网络瞬断。
- 冷却时间:同一个故障,至少间隔15分钟再发第二次,直到服务恢复,可以在
/tmp/alert_sent.lock记录时间戳。
-
区分级别:
- P0(紧急):服务完全不可用,400/500错误率飙升 -> 打电话。
- P1(高):响应慢、部分API不可用 -> 发送IM消息。
- P2(低):磁盘快满、SSL证书即将过期 -> 发邮件。
-
健康检查要有深度:
- 只检查
200 OK是不够的,一个数据库连接池耗尽或死锁的PHP应用,仍然能返回200,但无法响应业务请求,因此health_check.php必须检查关键依赖(DB、Redis、第三方API)。
- 只检查
-
监控者也需要高可用:
- 不要把
check_php_alive.sh和被监控的PHP服务部署在同一台机器上(否则它俩一起挂)。 - 如果预算允许,用两个不同云端数据中心的监控互相备份。
- 不要把
最小可行方案(30分钟内搭好)
- 注册 UptimeRobot 免费账号。
- 添加你的网站URL,设置检查间隔5分钟。
- 配置通知通道:手机App推送 + Slack/钉钉Webhook。
- 在项目中添加一个
health_check.php,返回OK作为监控目标(而非首页)。
这样可以保证,哪怕你的云服务器宕机、网络问题、PHP-FPM停止,你都会在5分钟内收到告警。