不灭的火

革命尚未成功,同志仍须努力下载JDK17

作者:AlbertWen  添加时间:2025-06-06 18:22:33  修改时间:2025-06-08 01:18:40  分类:01.Python基础  编辑

下面是一个 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)

使用说明

  1. 将上述脚本保存为 php_fpm_monitor.py
  2. 确保已安装 Python 3 和 psutil 库(可通过 pip install psutil 安装)
  3. 运行脚本:
python3 php_fpm_monitor.py

可选参数

  1. --threshold: CPU 使用率阈值(默认90%)
  2. --interval: 检查间隔时间(默认5秒)
  3. --duration: 允许高CPU持续的最长时间(默认30秒)

示例:设置阈值为80%,检查间隔10秒,最大持续时间60秒

python3 php_fpm_monitor.py --threshold 80 --interval 10 --duration 60

注意事项

  1. 脚本需要以 root 权限运行才能杀死进程
  2. 建议先在测试环境中验证脚本行为
  3. 可以结合系统服务(如 systemd)将脚本设置为后台运行
  4. 频繁杀死 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

参数说明:

  1. Description: 服务的描述
  2. User/Group: 运行脚本的用户和组
  3. WorkingDirectory: 脚本所在目录
  4. ExecStart: 启动命令(使用完整路径)
  5. Restart: 设置自动重启策略
  6. 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. 常用命令

  1. 启动服务:systemctl start php_fpm_monitor
  2. 停止服务:systemctl stop php_fpm_monitor
  3. 重启服务:systemctl restart php_fpm_monitor
  4. 查看日志:journalctl -u php_fpm_monitor -f

高级配置建议

  1. 日志记录:考虑在Python脚本中使用logging模块,并将日志输出到特定文件
  2. 环境变量:可以使用EnvironmentFile指令加载包含环境变量的文件
  3. 资源限制:可以设置内存限制、CPU优先级等
  4. 依赖关系:使用AfterRequires指定服务依赖关系

 

 

示例完整服务文件

[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