本文将深入探讨如何利用纯php语言,在不依赖外部shell命令的情况下,监控linux系统资源和php进程的详细信息。我们将重点介绍如何通过php的文件系统函数直接读取和解析`/proc`虚拟文件系统,从而获取系统负载、内存使用、活跃php进程数量及其资源消耗等全局数据,为系统管理员提供强大的php内建监控能力。
在系统管理和性能优化中,实时了解服务器的运行状态和应用程序的资源消耗至关重要。对于PHP应用程序而言,除了单个脚本自身的内存使用(如通过memory_get_usage()获取)和系统整体负载(如通过sys_getloadavg()获取)外,我们常常需要获取更全面的信息,例如当前所有活跃的PHP进程总数、它们占用的全局内存总量、由哪些用户运行、以及是否存在长时间运行的PHP进程等。
传统的做法可能涉及执行Shell命令(如ps aux | grep php、free -h等),但这在某些安全受限或追求纯PHP解决方案的环境中并不理想。幸运的是,在Linux系统上,PHP可以通过其标准的文件系统函数,直接访问一个名为/proc的特殊虚拟文件系统,从而获取这些详尽的系统和进程信息。
/proc文件系统是一个独特且强大的虚拟文件系统,它不存储在磁盘上,而是由Linux内核在内存中动态生成。它提供了对内核数据结构、系统配置和当前运行进程的实时视图。每个正在运行的进程都会在/proc目录下创建一个以其PID(进程ID)命名的子目录,例如/proc/1234。这些进程目录中包含了大量关于该进程的信息文件,如进程状态、命令行参数、内存映射等。
PHP与/proc文件系统的交互方式与读取普通文件无异。我们可以使用file_get_contents()读取文件内容,使用scandir()遍历目录,从而以纯PHP代码的方式获取这些系统级和进程级的数据。
通过/proc文件系统,我们可以轻松获取系统整体的资源使用情况。
PHP内置的sys_getloadavg()函数实际上就是对/proc/loadavg文件的封装。该文件包含三个浮点数,分别表示过去1分钟、5分钟和15分钟的平均系统负载。
示例:直接读取/proc/loadavg
(float)$parts[0],
'5_min' => (float)$parts[1],
'15_min' => (float)$parts[2]
];
}
return null;
}
// $load = getSystemLoadAvg();
// if ($load) {
// echo "System Load (1/5/15 min): {$load['1_min']} / {$load['5_min']} / {$load['15_min']}\n";
// }
?>/proc/meminfo文件提供了系统内存的详细统计信息,包括总内存、可用内存、空闲内存、缓存、缓冲区等。
示例:读取/proc/meminfo
获取单个PHP进程的详细信息是实现全局PHP环境监控的关键。
每个进程在/proc下都有一个以其PID命名的目录,例如/proc/1234。在这个目录中,有几个文件对我们特别有用:
以下是一个完整的PHP函数,用于收集并汇总当前系统上所有PHP进程的关键信息:
'`/proc` filesystem not found. This feature is Linux-specific.'];
}
//
获取所有PID目录
$pids = array_filter(scandir('/proc'), 'is_numeric');
// 获取系统启动时间 (btime) 和时钟频率 (_SC_CLK_TCK)
$systemBootTime = 0;
$clockTicks = 100; // 常见的_SC_CLK_TCK值,通常为100 jiffies/秒
if (file_exists('/proc/stat')) {
$statFileContent = file_get_contents('/proc/stat');
if (preg_match('/^btime\s*(\d+)/m', $statFileContent, $btimeMatches)) {
$systemBootTime = (int)$btimeMatches[1];
}
}
foreach ($pids as $pid) {
$cmdlinePath = "/proc/{$pid}/cmdline";
$statusPath = "/proc/{$pid}/status";
$statPath = "/proc/{$pid}/stat";
// 确保文件存在且可读
if (file_exists($cmdlinePath) && file_exists($statusPath) && file_exists($statPath)) {
$cmdline = file_get_contents($cmdlinePath);
// cmdline内容通常以null字节分隔,替换为空格以便解析
$cmdline = str_replace("\0", " ", $cmdline);
// 通过命令行判断是否为PHP进程 (php, php-fpm, php-cgi等)
if (preg_match('/php(?:-fpm|-cgi)?/i', $cmdline)) {
$statusContent = file_get_contents($statusPath);
$statContent = file_get_contents($statPath);
$processInfo = [
'pid' => (int)$pid,
'name' => '',
'memory_rss_kb' => 0, // Resident Set Size (物理内存占用)
'uid' => '',
'uptime_seconds' => 0,
'cmdline' => trim($cmdline)
];
// 解析status文件获取进程名、VmRSS和UID
if (preg_match('/^Name:\s*(.*)$/m', $statusContent, $matches)) {
$processInfo['name'] = trim($matches[1]);
}
if (preg_match('/^VmRSS:\s*(\d+)\s*kB$/m', $statusContent, $matches)) {
$processInfo['memory_rss_kb'] = (int)$matches[1];
$totalPhpMemoryKb += (int)$matches[1];
}
if (preg_match('/^Uid:\s*(\d+)/m', $statusContent, $matches)) {
$processInfo['uid'] = $matches[1];
$usersRunningPhp[$matches[1]] = true; // 记录运行进程的用户
}
// 解析stat文件获取进程启动时间并计算运行时长
// /proc/[PID]/stat 的第22个字段 (0-indexed 21) 是进程启动时间 (starttime)
$statFields = explode(' ', $statContent);
if (isset($statFields[21]) && $systemBootTime > 0) {
$startTimeJiffies = (int)$statFields[21];
// 进程启动时间(秒) = 系统启动时间(秒) + 进程启动时钟节拍 / 每秒时钟节拍
$processStartTimeSeconds = $systemBootTime + ($startTimeJiffies / $clockTicks);
$processUptimeSeconds = time() - $processStartTimeSeconds;
$processInfo['uptime_seconds'] = max(0, round($processUptimeSeconds));
// 判断是否为长时间运行进程 (例如,超过5分钟)
if ($processInfo['uptime_seconds'] > (5 * 60)) {
$longRunningProcessesCount++;
}
}
$phpProcesses[] = $processInfo;
}
}
}
return [
'total_scripts_running' => count($phpProcesses),
'users_running_process' => count($usersRunningPhp),
'process_with_more_than_5_minutes' => $longRunningProcessesCount,
'memory_global_assigned_to_all_php_kb' => $totalPhpMemoryKb,
'details' => $phpProcesses // 包含每个PHP进程的详细信息
];
}
// 示例用法:
$overview = getPhpProcessOverview();
if (isset($overview['error'])) {
echo "Error: " . $overview['error'] . "\n";
} else {
echo "--- PHP 进程概览 ---\n";
echo "总计运行中的PHP进程数: " . $overview['total_scripts_running'] . "\n";
echo "运行PHP进程的用户数: " . $overview['users_running_process'] . "\n";
echo "运行时间超过5分钟的PHP进程数: " . $overview['process_with_more_than_5_minutes'] . "\n";
echo "所有PHP进程占用的总物理内存 (RSS): " . round($overview['memory_global_assigned_to_all_php_kb'] / 1024, 2) . " MB\n";
echo "\n---
# php
# linux
# php函数
# 字节
# 虚拟内存
# ai
# linux系统
# 内存占用
# 封装
# 命令行参数
# 数据结构
# CGI
# 性能优化
# 文件系统
# 长时间
# 命令行
# 是一个
# 系统启动
# 遍历
# 以其
# 统计信息
# 时长
# 是否存在
相关文章:
公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?
平台云上自主建站:模板化设计与智能工具打造高效网站
如何用狗爹虚拟主机快速搭建网站?
网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?
如何在阿里云通过域名搭建网站?
如何在云主机快速搭建网站站点?
公司网站设计制作厂家,怎么创建自己的一个网站?
安徽网站建设与外贸建站服务专业定制方案
高端建站三要素:定制模板、企业官网与响应式设计优化
想学网站制作怎么学,建立一个网站要花费多少?
建站之星如何优化SEO以实现高效排名?
c++怎么使用类型萃取type_traits_c++ 模板元编程类型判断【方法】
如何优化Golang Web性能_Golang HTTP服务器性能提升方法
广州美橙建站如何快速搭建多端合一网站?
如何通过PHP快速构建高效问答网站功能?
网站制作知乎推荐,想做自己的网站用什么工具比较好?
存储型VPS适合搭建中小型网站吗?
制作网站怎么制作,*游戏网站怎么搭建?
车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?
如何在万网自助建站中设置域名及备案?
如何在宝塔面板中修改默认建站目录?
如何自定义建站之星模板颜色并下载新样式?
建站之星免费模板:自助建站系统与智能响应式一键生成
武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?
建站之星后台管理如何实现高效配置?
小型网站制作HTML,*游戏网站怎么搭建?
自助网站制作软件,个人如何自助建网站?
大学网站设计制作软件有哪些,如何将网站制作成自己app?
Python如何创建带属性的XML节点
如何基于云服务器快速搭建网站及云盘系统?
高端云建站费用究竟需要多少预算?
百度网页制作网站有哪些,谁能告诉我百度网站是怎么联系?
道歉网站制作流程,世纪佳缘致歉小吴事件,相亲网站身份信息伪造该如何稽查?
武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?
已有域名和空间如何搭建网站?
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
网站制作费用多少钱,一个网站的运营,需要哪些费用?
高端智能建站公司优选:品牌定制与SEO优化一站式服务
常州自助建站工具推荐:低成本搭建与模板选择技巧
如何在万网主机上快速搭建网站?
如何通过WDCP绑定主域名及创建子域名站点?
焦点电影公司作品,电影焦点结局是什么?
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
如何通过IIS搭建网站并配置访问权限?
如何用美橙互联一键搭建多站合一网站?
如何在Golang中处理模块冲突_解决依赖版本不兼容问题
建站IDE高效指南:快速搭建+SEO优化+自适应模板全解析
建站之星代理如何优化在线客服效率?
如何通过.red域名打造高辨识度品牌网站?
*请认真填写需求信息,我们会在24小时内与您取得联系。