PHP项目CPU负载过高如何触发告警通知

wen PHP项目 27

本文目录导读:

PHP项目CPU负载过高如何触发告警通知

  1. 方案一:服务器层面系统监控 + 通知脚本(最简单直接)
  2. 方案二:使用现成开源监控系统(如 Prometheus + Alertmanager)
  3. 方案三:使用商业 APM / 监控平台(如 Sentry、New Relic、Datadog)
  4. 方案四:结合 PHP 进程级监控(如需定位具体服务)
  5. 总结:推荐组合方案(成熟且成本低)

针对 PHP 项目 CPU 负载过高触发告警通知,可以构建一个监控 → 指标采集 → 阈值判定 → 告警通知的闭环体系,以下是几种常用且有效的方案,从简单到复杂排列:


服务器层面系统监控 + 通知脚本(最简单直接)

适用场景:没有复杂监控系统,想快速实现告警。

编写 Shell 脚本检测 CPU 负载

在服务器上创建一个脚本 /usr/local/bin/cpu_alert.sh

#!/bin/bash
# CPU负载阈值 (可根据核心数调整,CPU核心数*1.5)
LOAD_THRESHOLD=2.0
# 通知间隔(秒),防止频繁告警
NOTIFY_INTERVAL=300
# 当前 1分钟平均负载
CURRENT_LOAD=$(uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | sed 's/ //g')
# 负载对比(浮点数比较)
if (( $(echo "$CURRENT_LOAD > $LOAD_THRESHOLD" | bc -l) )); then
    # 检查上次通知时间,避免重复告警
    LAST_NOTIFY_FILE="/tmp/cpu_alert_last_notify"
    CURRENT_TIME=$(date +%s)
    if [ -f "$LAST_NOTIFY_FILE" ]; then
        LAST_NOTIFY=$(cat "$LAST_NOTIFY_FILE")
        TIME_DIFF=$(( CURRENT_TIME - LAST_NOTIFY ))
    else
        TIME_DIFF=$NOTIFY_INTERVAL  # 首次触发
    fi
    if [ $TIME_DIFF -ge $NOTIFY_INTERVAL ]; then
        # 发送通知(示例:钉钉、企业微信、飞书、邮件等)
        MESSAGE="[告警] 服务器 $(hostname) CPU负载过高,当前负载: $CURRENT_LOAD (阈值: $LOAD_THRESHOLD)"
        # 示例:调用外部Webhook (钉钉机器人)
        curl -s -X POST "https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN" \
             -H "Content-Type: application/json" \
             -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"$MESSAGE\"}}" > /dev/null 2>&1
        # 记录通知时间
        echo "$CURRENT_TIME" > "$LAST_NOTIFY_FILE"
    fi
fi

设置 Crontab 定时执行

# 每分钟检查一次
* * * * * /bin/bash /usr/local/bin/cpu_alert.sh

优点:极简、不依赖第三方平台。
缺点:只能监控服务器整体负载,无法关联 PHP 进程(比如是哪个PHP-FPM池或者哪个Web服务引起的)。


使用现成开源监控系统(如 Prometheus + Alertmanager)

适用场景:多台服务器、需要历史数据和可视化、想统一管理告警。

部署架构

服务器 (Node Exporter) → Prometheus (采集和存储) → Alertmanager (告警管理) → 通知渠道

关键配置示例

Prometheus 告警规则 (cpu_alert.yml):

groups:
  - name: cpu_alerts
    rules:
      - alert: HighCpuLoad
        expr: node_load1 > (count(node_cpu_seconds_total{mode="idle"}) * 1.5)
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "服务器 {{ $labels.instance }} CPU负载过高"
          description: "当前负载: {{ $value }} (历史平均值)"

Alertmanager 通知配置(以钉钉为例):

receivers:
  - name: 'webhook'
    webhook_configs:
      - url: 'https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN'
        send_resolved: true

优点:功能全面、可扩展、支持多维度告警。
缺点:需要部署和维护 Prometheus 生态,学习成本略高。


使用商业 APM / 监控平台(如 Sentry、New Relic、Datadog)

适用场景:已有商业监控预算,或需要深度应用性能监控。

  • Datadogmonitor "avg:system.cpu.user{*}" > 80,可直接对接 Slack、PagerDuty。
  • Sentry:可以监控 PHP 慢事务和高 CPU 消耗的异常。
  • 阿里云 / 腾讯云云监控:如果服务器在云上,直接使用云厂商的告警服务(如云监控 + 云函数 + 短信/电话通知)。

优点:开箱即用,免运维,功能强大。
缺点:费用较高,数据可能出网。


结合 PHP 进程级监控(如需定位具体服务)

如果想知道是哪个 PHP 服务(网站、队列、定时任务)导致 CPU 过高,需要在方案一二的基础上增加进程级别监控

示例:监控具体 PHP-FPM pool 的 CPU 使用

# 获取特定 pool 的进程CPU总和
ps aux | grep 'php-fpm: pool www' | awk '{sum+=$3} END {print sum}'

告警脚本逻辑

  1. 整体负载高 → 进入排查流程
  2. 再计算 php-fpm: pool worker 的 CPU 总和 → 如果占比超过 60% → 通知“Worker 池消耗高”
  3. 或解析 strace / top 定位慢请求

更专业的做法:使用 (int) sys_getloadavg()[0] 在 PHP 代码内部做熔断或降级,并在业务层触发告警(例如记录日志、调用 Webhook)。


推荐组合方案(成熟且成本低)

方案 工具
基础监控 Shell 脚本 + Crontab(方案一) 守护进程
进程定位 脚本分析 php-fpm pool 或单个 PHP worker ps, top, strace
告警渠道 Webhook 到钉钉/企业微信/Slack curl + Webhook URL

最佳实践步骤

  1. 先用方案一快速实现告警(1小时搞定)
  2. 后期如果服务器增多,迁移到方案二(Prometheus)
  3. 如果业务需要精细到每个接口的 CPU 消耗,再上方案三或 APM

这样既能快速响应问题,又不至于一开始就引入过重的架构。

抱歉,评论功能暂时关闭!