下面是一个 Python 脚本,用于监控 PHP-FPM 进程的 CPU 使用率,并在超过阈值时自动杀死这些进程。
#!/usr/bin/env python3
import os
import psutil
import time
import argparse
from datetime import datetime
def monitor_php_fpm(cpu_threshold, check_interval, max_duration):
    """
    监控 PHP-FPM 进程,杀死 CPU 使用率超过阈值的进程
    
    参数:
        cpu_threshold (float): CPU 使用率阈值(百分比)
        check_interval (int): 检查间隔(秒)
        max_duration (int): 最大允许持续时间(秒)
    """
    print(f"开始监控 PHP-FPM 进程,CPU 阈值: {cpu_threshold}%,检查间隔: {check_interval}秒")
    
    # 存储进程和其高CPU使用的开始时间
    high_cpu_processes = {}
    
    while True:
        try:
            current_time = time.time()
            
            # 查找所有 PHP-FPM 进程
            for proc in psutil.process_iter(['pid', 'name', 'cmdline', 'cpu_percent']):
                try:
                    # 检查是否是 PHP-FPM 进程
                    if proc.info['name'] == 'php-fpm' or 'php-fpm' in ' '.join(proc.info['cmdline'] or []):
                        cpu_percent = proc.cpu_percent(interval=0.1)
                        
                        if cpu_percent > cpu_threshold:
                            pid = proc.info['pid']
                            if pid not in high_cpu_processes:
                                high_cpu_processes[pid] = current_time
                                print(f"[{datetime.now()}] 检测到高CPU进程 PID: {pid}, CPU: {cpu_percent}%")
                            else:
                                duration = current_time - high_cpu_processes[pid]
                                if duration >= max_duration:
                                    # 杀死进程
                                    proc.kill()
                                    print(f"[{datetime.now()}] 已杀死进程 PID: {pid}, 持续高CPU: {duration:.1f}秒, CPU: {cpu_percent}%")
                                    del high_cpu_processes[pid]
                        else:
                            # CPU 恢复正常,从监控中移除
                            if proc.info['pid'] in high_cpu_processes:
                                del high_cpu_processes[proc.info['pid']]
                except (psutil.NoSuchProcess, psutil.AccessDenied):
                    continue
            
            # 清理已经不存在的进程
            for pid in list(high_cpu_processes.keys()):
                if not psutil.pid_exists(pid):
                    del high_cpu_processes[pid]
            
            time.sleep(check_interval)
            
        except KeyboardInterrupt:
            print("\n监控已停止")
            break
        except Exception as e:
            print(f"发生错误: {e}")
            time.sleep(check_interval)
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='监控 PHP-FPM 进程 CPU 使用率并自动杀死高占用进程')
    parser.add_argument('--threshold', type=float, default=90.0, help='CPU 使用率阈值(百分比)')
    parser.add_argument('--interval', type=int, default=5, help='检查间隔(秒)')
    parser.add_argument('--duration', type=int, default=30, help='最大允许持续时间(秒)')
    
    args = parser.parse_args()
    
    monitor_php_fpm(args.threshold, args.interval, args.duration)
使用说明
- 将上述脚本保存为 
php_fpm_monitor.py - 确保已安装 Python 3 和 psutil 库(可通过 
pip install psutil安装) - 运行脚本:
 
python3 php_fpm_monitor.py
可选参数
--threshold: CPU 使用率阈值(默认90%)--interval: 检查间隔时间(默认5秒)--duration: 允许高CPU持续的最长时间(默认30秒)
示例:设置阈值为80%,检查间隔10秒,最大持续时间60秒
python3 php_fpm_monitor.py --threshold 80 --interval 10 --duration 60
注意事项
- 脚本需要以 root 权限运行才能杀死进程
 - 建议先在测试环境中验证脚本行为
 - 可以结合系统服务(如 systemd)将脚本设置为后台运行
 - 频繁杀死 PHP-FPM 进程可能影响网站正常运行,建议先调查高CPU使用的原因
 
将Python脚本包装成systemctl服务
将Python脚本作为systemd服务运行可以让你的脚本在系统启动时自动运行,并且可以方便地管理(启动、停止、查看状态等)。以下是详细步骤:
1. 创建服务文件
在/etc/systemd/system/目录下创建一个以.service结尾的服务文件,例如:
vim /etc/systemd/system/php_fpm_monitor.service
2. 编写服务文件内容
[Unit] Description=PHP-FPM Monitor Service After=network.target [Service] User=root Group=root WorkingDirectory=/www/scripts ExecStart=/usr/bin/python3 /www/scripts/php_fpm_monitor.py Restart=always RestartSec=3 Environment=PYTHONUNBUFFERED=1 [Install] WantedBy=multi-user.target
参数说明:
- Description: 服务的描述
 - User/Group: 运行脚本的用户和组
 - WorkingDirectory: 脚本所在目录
 - ExecStart: 启动命令(使用完整路径)
 - Restart: 设置自动重启策略
 - Environment: 设置环境变量(PYTHONUNBUFFERED=1确保日志实时输出)
 
3.重新加载systemd配置
systemctl daemon-reload
4.启用并启动服务
# 设置服务 systemctl enable php_fpm_monitor.service # 启动服务 systemctl start php_fpm_monitor.service
5.检查服务状态
systemctl status php_fpm_monitor.service
6. 常用命令
- 启动服务:
systemctl start php_fpm_monitor - 停止服务:
systemctl stop php_fpm_monitor - 重启服务:
systemctl restart php_fpm_monitor - 查看日志:
journalctl -u php_fpm_monitor -f 
高级配置建议
- 日志记录:考虑在Python脚本中使用logging模块,并将日志输出到特定文件
 - 环境变量:可以使用
EnvironmentFile指令加载包含环境变量的文件 - 资源限制:可以设置内存限制、CPU优先级等
 - 依赖关系:使用
After和Requires指定服务依赖关系 
示例完整服务文件
[Unit] Description=Web Scraping Service After=network.target postgresql.service [Service] User=scraper Group=scraper WorkingDirectory=/home/scraper/web_scraper EnvironmentFile=/home/scraper/web_scraper/.env ExecStart=/home/scraper/web_scraper/venv/bin/python /home/scraper/web_scraper/main.py Restart=on-failure RestartSec=30 StandardOutput=file:/var/log/web_scraper/out.log StandardError=file:/var/log/web_scraper/err.log [Install] WantedBy=multi-user.target