Ubuntu20.04服务器shell_exec重复执行PHP脚本致CPU100%求助
解决Ubuntu 20.04下PHP8.1 shell_exec触发大量重复进程导致CPU占用100%的问题
紧急缓解CPU占用
先杀掉所有相关进程,快速降低CPU负载:
# 杀掉直接执行php脚本的进程 pkill -f "php /var/www/html/broadcast/new_broadcast.php" # 杀掉通过sh -c间接调用的进程 pkill -f "sh -c php /var/www/html/broadcast/new_broadcast.php"
排查脚本核心问题
大量重复进程的根源几乎都是脚本本身逻辑异常,优先检查:
- 检查循环调用:打开
new_broadcast.php,确认里面没有再次调用shell_exec或其他方式触发自身执行的逻辑。 - 检查死循环:查看脚本是否存在未设置退出条件的循环,导致进程无法正常终止、不断积累。
- 添加执行日志:在
new_broadcast.php开头加入日志代码,追踪进程生成情况:
执行后查看日志,判断是同一进程持续运行还是不断生成新进程。$logPath = '/var/log/new_broadcast_exec.log'; $logContent = date('Y-m-d H:i:s') . " | PID: " . getmypid() . " | Parent PID: " . posix_getppid() . "\n"; file_put_contents($logPath, $logContent, FILE_APPEND); - 确认退出逻辑:确保脚本完成任务后通过
exit()或自然结束,没有阻塞、挂起的情况。
优化shell_exec调用方式
- 使用PHP绝对路径:避免系统通过
sh -c间接调用,直接指定PHP8.1的绝对路径(先通过which php8.1确认路径):// 替换为你的PHP8.1实际路径 $e = shell_exec("/usr/bin/php8.1 /var/www/html/broadcast/new_broadcast.php"); print_r($e); - 后台执行(非必要等待结果时):如果不需要等待脚本执行结果,改用
exec并后台运行,避免阻塞主进程导致重复触发:
注:exec("/usr/bin/php8.1 /var/www/html/broadcast/new_broadcast.php > /dev/null 2>&1 &");> /dev/null 2>&1用于重定向输出,避免输出缓冲区阻塞。
添加进程互斥机制
通过锁文件确保同一时间只有一个脚本实例运行,彻底防止进程堆积:
在new_broadcast.php开头加入以下代码:
$lockFile = '/tmp/new_broadcast.lock'; // 创建锁文件并尝试获取排他锁(非阻塞) $lockHandle = fopen($lockFile, 'w'); if (!flock($lockHandle, LOCK_EX | LOCK_NB)) { // 已有实例运行,直接退出 exit("Script is already running\n"); } // -------------------------- // 这里放你的脚本核心逻辑 // -------------------------- // 脚本结束后释放锁并删除锁文件 flock($lockHandle, LOCK_UN); fclose($lockHandle); unlink($lockFile);
排查Web端触发原因(如果是Web请求触发)
- 查看Web服务器日志(Apache的
/var/log/apache2/access.log或Nginx的/var/log/nginx/access.log),确认是否有大量重复请求触发该脚本。 - 检查客户端是否存在重复提交、自动重试的逻辑。
- 调整PHP-FPM或Web服务器的进程配置,避免因进程管理异常导致重复执行。
内容的提问来源于stack exchange,提问作者xxme
相关产品推荐
相关产品推荐

