本文提供一套基于 PHP 的服务器异常监控告警解决方案。通过调用飞书自定义机器人 Webhook 接口,实现 CPU 负载过高、内存溢出、磁盘空间不足及 PHP 致命错误等异常情况的实时推送。教程涵盖签名校验配置、cURL 请求封装、异常捕获逻辑及定时任务部署,适用于 Linux 环境下的生产服务器监控,帮助运维人员快速响应系统故障。

环境准备与飞书机器人配置
在编写 PHP 代码前,需在飞书群聊中创建自定义机器人并获取安全凭证。
-
创建机器人:进入飞书群设置,选择“群机器人” > “添加机器人” > “自定义机器人”。
-
安全设置:为保障接口安全,建议开启“签名校验”(Sign Verification)。系统会生成
Webhook 地址和签名密钥(Secret)。 -
权限配置:确保机器人拥有发送消息的权限。
PHP 生成飞书签名与请求封装
飞书机器人开启签名校验后,PHP 服务端需生成时间戳与签名才能成功发送消息。以下代码封装了发送逻辑,可直接复用。
<?php
/**
* 飞书机器人消息推送类
*/
class FeishuNotifier
{
private $webhookUrl;
private $secret;
public function __construct($webhookUrl, $secret)
{
$this->webhookUrl = $webhookUrl;
$this->secret = $secret;
}
/**
* 生成带签名的请求头
* @return array
*/
private function generateSign()
{
$timestamp = time();
$stringToSign = $timestamp . "\n" . $this->secret;
$sign = base64_encode(hash_hmac('sha256', $stringToSign, $this->secret, true));
return [
'timestamp' => $timestamp,
'sign' => $sign
];
}
/**
* 发送文本消息
* @param string $content
* @return bool
*/
public function sendText($content)
{
$signData = $this->generateSign();
$postData = json_encode([
'timestamp' => $signData['timestamp'],
'sign' => $signData['sign'],
'msg_type' => 'text',
'content' => [
'text' => $content
]
]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->webhookUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 设置超时时间,防止阻塞
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $httpCode == 200;
}
}监控指标采集与告警逻辑
根据服务器常见的异常场景,编写监控脚本。以下示例监控磁盘空间与 PHP 错误日志。
1. 磁盘空间监控
当磁盘使用率超过 90% 时触发告警。
/**
* 检查磁盘使用率
* @param string $path 监控路径
* @param int $threshold 阈值(百分比)
*/
function checkDiskUsage($path = '/', $threshold = 90)
{
$free = shell_exec('df -h ' . escapeshellarg($path));
preg_match('/(\d+)%/', $free, $matches);
$usage = isset($matches[1]) ? (int)$matches[1] : 0;
if ($usage >= $threshold) {
return "【服务器告警】磁盘空间不足\n路径:{$path}\n当前使用率:{$usage}%\n阈值:{$threshold}%";
}
return null;
}2. PHP 致命错误监控
监控 PHP 错误日志文件,若检测到新的 Fatal error,立即推送。
/**
* 检查PHP错误日志
* @param string $logFile 日志路径
*/
function checkPhpErrors($logFile)
{
if (!file_exists($logFile)) {
return null;
}
// 读取最后10行,避免日志过大
$lines = shell_exec("tail -n 10 " . escapeshellarg($logFile));
if (strpos($lines, 'PHP Fatal error') !== false) {
return "【PHP致命错误】\n日志文件:{$logFile}\n最新错误片段:\n" . substr($lines, -500);
}
return null;
}整合脚本与定时任务部署
将上述功能整合为一个主执行脚本 monitor.php,并通过 Linux Cron Job 实现定时轮询。
<?php
// monitor.php
require 'FeishuNotifier.php';
// 配置信息
$webhook = 'https://open.feishu.cn/open-apis/bot/v2/hook/xxxx-xxxx';
$secret = '你的签名密钥';
$notifier = new FeishuNotifier($webhook, $secret);
$alerts = [];
// 执行监控检查
$diskAlert = checkDiskUsage('/', 90);
if ($diskAlert) {
$alerts[] = $diskAlert;
}
$phpAlert = checkPhpErrors('/var/log/php-fpm/error.log');
if ($phpAlert) {
$alerts[] = $phpAlert;
}
// 发送汇总告警
if (!empty($alerts)) {
$serverIp = $_SERVER['SERVER_ADDR'] ?? gethostname();
$message = "服务器IP:{$serverIp}\n\n" . implode("\n\n---\n\n", $alerts);
$notifier->sendText($message);
}配置 Crontab
使用 crontab -e 命令添加定时任务,建议每分钟执行一次:
* * * * * /usr/bin/php /path/to/monitor.php >/dev/null 2>&1优化建议
-
告警频率限制:为避免告警风暴,可在脚本中加入文件锁(flock)或缓存机制(Redis),限制同一类型告警在 5 分钟内仅发送一次。
-
多维度监控:可扩展监控 CPU 负载(
sys_getloadavg())、内存使用率(memory_get_usage())及关键服务进程状态。 -
日志持久化:将告警记录写入本地数据库或日志文件,便于后续追溯与分析。
通过上述方案,即可构建一套低延迟、高可靠的 PHP 服务器异常实时告警系统,有效提升线上服务的稳定性与运维效率。

