本文目录导读:

针对PHP项目的值班与告警响应体系设计,需要覆盖监控层、告警层、响应层以及复盘层,以下是完整的实施方案:
监控层(前置发现)
应用层监控(PHP特有)
// 使用 PHP-FPM status page 监控进程健康
// 配置 nginx 访问 /status 页面
location ~ ^/(status|ping)$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
// 自定义健康检查端点
Route::get('/health', function() {
try {
// 检查数据库连接
DB::connection()->getPdo();
// 检查 Redis
Redis::ping();
// 检查队列(如果使用)
Queue::size();
return response()->json(['status' => 'healthy'], 200);
} catch (\Exception $e) {
Log::critical('Health check failed', ['error' => $e->getMessage()]);
return response()->json(['status' => 'unhealthy', 'error' => $e->getMessage()], 500);
}
});
关键指标采集(Prometheus + 自定义Exporter)
// 安装 prometheus_pushgateway 依赖
// composer require promphp/prometheus_client_php
// 在中间件中采集指标
namespace App\Http\Middleware;
class MetricsMiddleware {
public function handle($request, \Closure $next) {
$start = microtime(true);
$response = $next($request);
$duration = microtime(true) - $start;
$statusCode = $response->status();
// 记录请求数
$counter = Counter::namespace('app')->name('http_requests_total')
->help('Total HTTP requests')
->label('method', 'route', 'status')
->incBy(1, [$request->method(), $request->path(), $statusCode]);
// 记录请求耗时
$histogram = Histogram::namespace('app')->name('http_request_duration_seconds')
->help('HTTP request duration')
->label('method', 'route')
->observe($duration, [$request->method(), $request->path()]);
// 记录慢查询
if ($duration > 1.0) {
$counter->inc(1, ['method' => 'slow_request', 'route' => $request->path()]);
}
return $response;
}
}
基础设施监控
# docker-compose 监控栈
version: '3.8'
services:
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
grafana:
image: grafana/grafana
ports:
- "3000:3000"
node_exporter:
image: prom/node-exporter
network_mode: "host"
php_fpm_exporter:
image: bakins/php-fpm-exporter
environment:
- PHP_FPM_SCRAPE_URI=http://php-app/status
告警层(分级响应)
告警等级定义
| 等级 | 颜色 | 响应时间 | 示例场景 |
|---|---|---|---|
| P0 致命 | 🔴 红色 | 立即响应 | 数据库宕机、500错误率>5%、全线崩溃 |
| P1 严重 | 🟠 橙色 | 5分钟内 | 支付接口超时、核心功能不可用、慢查询>3秒 |
| P2 警告 | 🟡 黄色 | 30分钟内 | 错误率上升、磁盘使用>80%、PHP进程飚升 |
| P3 提示 | 🔵 蓝色 | 工作日内 | 缓存命中率下降、代码覆盖率下降 |
告警规则配置(Prometheus Alertmanager)
groups:
- name: php_app_alerts
interval: 30s
rules:
# P0: 应用完全宕机
- alert: ApplicationDown
expr: up{job="php-app"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "PHP应用不可访问"
description: "实例 {{ $labels.instance }} 已下线超过1分钟"
# P1: 高错误率
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) > 0.05
for: 2m
labels:
severity: major
annotations:
summary: "5XX错误率超过5%"
description: "当前错误率 {{ $value | humanizePercentage }}"
# P2: PHP进程异常
- alert: PhpFpmBusy
expr: php_fpm_active_processes / php_fpm_max_children > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "PHP-FPM进程使用率超过80%"
description: "当前使用率 {{ $value | humanizePercentage }}"
告警通知渠道
graph LR
A[告警事件] --> B{自动决策}
B -->|P0/P1| C[电话/短信]
B -->|P2| D[企业微信/Slack]
B -->|P3| E[邮件/工单系统]
C --> F[值班负责人]
D --> G[技术群组]
E --> H[项目协同]
企业微信机器人配置示例:
// 发送告警到企业微信群
class WeWorkAlert {
public static function send($level, $message) {
$webhook = config("alert.webhook.{$level}");
$payload = [
'msgtype' => 'markdown',
'markdown' => [
'content' => "## 🚨 {$level} 告警\n> **项目**: PHP Core\n> **时间**: " . now() . "\n> **详情**: {$message}"
]
];
Http::post($webhook, $payload);
}
}
响应层(标准流程)
值班安排(轮值表)
// 使用 oncall 轮值系统
// 使用 PagerDuty / Opsgenie 或自建系统
class OnCallSchedule {
public static function getCurrentOnCall() {
$schedule = [
['name' => '张三', 'phone' => '138xxxx', 'start' => '2024-01-01', 'end' => '2024-01-07'],
['name' => '李四', 'phone' => '139xxxx', 'start' => '2024-01-08', 'end' => '2024-01-14'],
];
$now = now();
return collect($schedule)->first(function($shift) use ($now) {
return $now->between($shift['start'], $shift['end']);
});
}
}
故障响应 SOP(标准操作流程)
P0 级别响应流程:
确认告警(2分钟内)
- 回复告警通知,表明已接手
- 创建故障工单(如 Jira)
2. 初步诊断(5分钟内)
- 检查 Grafana 仪表盘
- 查看 PHP 错误日志
- 检查服务器负载
3. 止血操作(15分钟内)
- 重启 PHP-FPM:sudo systemctl restart php8.1-fpm
- 回滚最近部署:git revert HEAD
- 扩容服务:kubectl scale deployment php-app --replicas=5
4. 根本原因分析(1小时内)
- 查看慢查询日志
- 检查最近代码变更
- 分析 Xdebug 性能追踪
5. 修复与验证
- 部署修复代码
- 持续监控15分钟
- 更新故障报告
常见故障自动恢复脚本
# auto_heal.sh - 自动恢复脚本
#!/bin/bash
# 检查 PHP-FPM 状态
if ! pgrep php-fpm > /dev/null; then
echo "[$(date)] PHP-FPM 已崩溃,尝试重启..."
systemctl restart php8.1-fpm
sleep 5
if pgrep php-fpm > /dev/null; then
echo "[$(date)] 重启成功"
# 发送恢复通知
curl -X POST -H "Content-Type: application/json" \
-d '{"msgtype":"text","text":{"content":"PHP-FPM 已自动恢复"}}' \
$WEBHOOK_URL
else
echo "[$(date)] 重启失败,需要人工介入"
# 升级告警
echo "PHP-FPM 自动恢复失败" | mail -s "P0 告警" oncall@company.com
fi
fi
# 检查磁盘空间
DISK_USAGE=$(df / | awk '{print $5}' | tail -1 | sed 's/%//')
if [ $DISK_USAGE -gt 90 ]; then
echo "[$(date)] 磁盘使用率超过90%,清理临时文件..."
find /tmp -type f -atime +7 -delete
find /var/log/php -type f -mtime +30 -delete
# 如果还是不够,扩展磁盘(云环境)
# aws ec2 modify-volume --volume-id vol-xxx --size +10
fi
复盘层(持续改进)
故障报告模板(Postmortem)
# 故障报告:2024-01-15 数据库连接风暴 ## 严重等级 P1 (严重) ## 时间线 - 14:30 告警触发(错误率>5%) - 14:32 值班人员确认 - 14:35 发现数据库连接池耗尽 - 14:40 增加连接池大小(临时止血) - 15:20 找到根本原因(慢查询未优化) - 15:45 优化SQL并部署 - 16:00 确认恢复 ## 根因分析 - 直接原因:`SELECT * FROM orders WHERE status = 'pending'` 未加索引,导致全表扫描 - 根本原因:代码审查不严格,未检查SQL执行计划 - 系统原因:缺少慢查询告警 ## 改进措施 - [ ] 添加慢查询监控(阈值:500ms) - [ ] 设置最大连接池告警(使用率>70%) - [ ] 代码审查增加SQL检查步骤 - [ ] 建立数据库索引规范文档 ## 负责人 - 值班:张三 - 修复:李四 - 复盘:王五
值班统计看板
-- 统计值班效果
SELECT
oncall_person,
COUNT(*) as incidents,
AVG(response_time) as avg_response,
AVG(resolution_time) as avg_resolution,
COUNT(CASE WHEN severity = 'P0' THEN 1 END) as p0_count
FROM incident_reports
WHERE created_at > DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY oncall_person;
值班交接本
# 值班交接记录示例
## 当前状态
- PHP版本:8.1.27
- 当前在线人数:2,345
- Redis内存使用:65%
- 告警静默规则:server-03 正在维护(维护窗口 22:00-02:00)
## 进行中的问题
1. #INC-456 - 用户上传图片偶尔失败(PHP内存限制问题,已分配开发修复中)
## 最近变更
- 2024-01-15 14:30 部署了 v2.3.1 (修复支付回调死循环)
- 2024-01-15 16:00 数据库添加了 orders.status 索引
## 重点关注
- 新支付渠道(Stripe)3D验证在部分国家失败
- 日志收集器磁盘剩余 15%,明天需要清理
## 值班人员
- 交班:张三 (138xxxx)
- 接班:李四 (139xxxx)
工具链推荐
开源方案
| 工具 | 用途 | 部署方式 |
|---|---|---|
| Prometheus + Grafana | 监控 + 可视化 | Docker |
| Alertmanager | 告警路由 | 自带 |
| PagerDuty | 值班调度 | SaaS |
| Sentry | PHP错误追踪 | 开源版 |
| OpenTelemetry | 链路追踪 | 代码集成 |
付费方案(推荐)
| 服务 | 优势 | 价格 |
|---|---|---|
| Datadog | 全栈监控 | 按主机 |
| New Relic | APM深度 | 按用量 |
| Opsgenie | 告警管理 | 按用户 |
| Better Uptime | 简单易用 | 低门槛 |
值班制度关键点
-
值班交接仪式
- 每天17:00 值班交接群内通报
- 必须阅读前一天的故障报告
- 新值班人员需要确认告警静默规则
-
告警疲劳防护
- 设置告警静默期(相同问题1小时内不重复告警)
- 阈值动态调整(根据业务低谷/高峰期调整灵敏度)
- 3天内未处理的告警自动升级
-
新人培养
- 入职第1周:跟随值班(只观察不操作)
- 第2-3周:处理P3告警
- 第4周:独立值班(需师傅背书)
-
奖惩制度
- 避免P0事故:奖励 $500
- 发现并修复潜在问题:$100
- 值班期间未及时响应:扣除当天补贴
这个体系涵盖了从监控发现到最终复盘优化的完整闭环,能够有效保障PHP项目的稳定运行,关键是要持续迭代——每次故障都是改进的机会。