tag 标签: 监控服务器

相关博文
  • 热度 3
    2024-10-31 16:16
    214 次阅读|
    0 个评论
    前言 当我们需要获取linux服务器的状态时,比如APP要获取服务器状态、网页要显示服务器状态,那么我们就可以用exec函数来命令linux,然后读取linux的数据,但是exec函数在PHP中都是推荐禁用的,因为exec函数可能会被注入恶意命令,从而导致服务器被攻击、数据泄露等安全问题。 所以本文不推荐使用exec函数,我们可以通过读取系统文件,来获取状态。 在Linux系统中,/proc目录是一个非常重要的特殊目录,它实际上是一个虚拟文件系统(proc文件系统),提供了对内核和系统进程信息的实时访问。 源码免费下载:https://mbb.eet-china.com/download/316368.html proc目录介绍 /proc目录中的数据并不占用磁盘空间,而是由内核动态生成的,内容实时反映了系统和进程的当前状态。 这个目录为用户和管理员提供了一个方便的接口,以监控和管理系统的状态。 (一)系统信息 ①/proc/cpuinfo:提供有关CPU的信息,包括型号、核心数量、频率 ②/proc/meminfo:显示有关内存使用情况的信息,包括总内存、可用内存、缓存 ③/proc/version:显示当前运行的Linux内核版本和编译信息 ④/proc/devices:列出所有已注册的设备及其驱动程序 ⑤/proc/partitions:显示磁盘分区的信息 ⑥/proc/stat: 系统性能的统计信息,如 CPU 使用情况、中断数量、上下文切换次数 (二)网络信息 ①/proc/net/:包含网络相关的信息,如网络连接、路由表、网络接口统计 ②/proc/net/tcp:显示TCP连接的信息 ③/proc/net/udp:显示UDP连接的信息 编写PHP接口 (一)内存信息/proc/meminfo ①我们先看一下文件的内容,发现由两部分组成,一部分是标签,另一部分就是标签对应的数值 所以思路就是将所需标签的数值提取出来就可以了 需要提取:总内存MemTotal、未使用内存MemFree、缓冲区内存Buffers、缓存Cached 可用内存 =未使用内存MemFree +缓冲区内存Buffers +缓存Cached 已用内存 = 总内存 - 可用内存 使用率 = (已用内存/总内存)* 100 ②代码展示 function getMemoryInfo ( ) { // 读取 /proc/meminfo 文件内容 $meminfo = file ( '/proc/meminfo' ); $freeMemory = 0 ; $availableMemory = 0 ; $totalMemory = 0 ; foreach ( $meminfo as $line ) { if ( strpos ( $line , 'MemTotal:' ) === 0 ) { // 获取总内存(MemTotal) list (, $memTotalKb ) = explode ( ':' , trim ( $line )); $totalMemory = ( int ) $memTotalKb * 1024 ; // 转换为字节 } elseif ( strpos ( $line , 'MemFree:' ) === 0 ) { // 获取完全没有被使用的内存(MemFree) list (, $memFreeKb ) = explode ( ':' , trim ( $line )); $freeMemory = ( int ) $memFreeKb * 1024 ; // 转换为字节 } elseif ( strpos ( $line , 'Buffers:' ) === 0 ) { // 获取被用作缓冲区的内存(Buffers) list (, $buffersKb ) = explode ( ':' , trim ( $line )); $buffersMemory = ( int ) $buffersKb * 1024 ; // 转换为字节 } elseif ( strpos ( $line , 'Cached:' ) === 0 ) { // 获取被用作缓存的内存(Cached) list (, $cachedKb ) = explode ( ':' , trim ( $line )); $cachedMemory = ( int ) $cachedKb * 1024 ; // 转换为字节 } } // 可用内存 = MemFree + Buffers + Cached $availableMemory = $freeMemory + $buffersMemory + $cachedMemory ; // 计算内存使用率(百分比) $usedMemory = $totalMemory - $availableMemory ; $memoryUsagePercent = ( $usedMemory / $totalMemory ) * 100 ; // 获取内存信息 $memoryInfo = getMemoryInfo (); // 打印空闲内存、可用内存、总内存和内存使用率(以MB为单位和百分比表示) echo "Free Memory: " . number_format ( $memoryInfo / ( 1024 * 1024 ), 2 , '.' , '' ) . " MB\n" ; echo "Available Memory: " . number_format ( $memoryInfo / ( 1024 * 1024 ), 2 , '.' , '' ) . " MB\n" ; echo "Total Memory: " . number_format ( $memoryInfo / ( 1024 * 1024 ), 2 , '.' , '' ) . " MB\n" ; echo "Memory Usage: " . number_format ( $memoryInfo , 2 , '.' , '' ) . " %\n" ; ③代码解析 foreach ( $meminfo as $line ) 使用foreach循环遍历$meminfo数组中的每一行。$line为当前的行 strpos ( $line , 'MemTotal:' ) === 0 strpos函数用于查找字符串在另一个字符串中首次出现的位置:strpos($line, 'MemTotal:') === 0,MemTotal在$line中首次出现 list (, $memTotalKb ) = explode ( ':' , trim ( $line )); trim($line);用于将$line首位的空白去掉 explode(':', trim($line));explode将处理后的line从冒号":"开始分割,分成数组 去空白:MemTotal: 16384256 kB 分割成数组: list(, $cachedKb);读取数组的信息,第一位是空字符,即忽略MemTotal,从第二位获取,则16384256 kB $cachedMemory = (int)$cachedKb * 1024; // 转换为字节 ,转不转都可以 return ; 返回函数,后续使用时,$memoryInfo = getMemoryInfo(); 调用$memoryInfo ,简洁明了 number_format ( $memoryInfo / ( 1024 * 1024 ), 2 , '.' , '' ) 由于我取值时转为了字节,所以字节转到MB时,要计算,要让字节/1024*1024 然后取值2位小数,小数标点符号位“.”,不使用千位分隔符 (二)网络信息/proc/net/dev ①观察文件,前两行都为无效内容,所以在遍历的时候要忽略前两行,我们需要的数据为lo和wlan0两行的接收、发送数据 用一秒后的数据,减去一秒前的数据,就可以得到1秒数据大小 ②代码展示 // 函数:获取所有网络接口的流量信息 function getAllNetworkTraffic ( ) { // 读取 /proc/net/dev 文件的内容 $stats = file ( '/proc/net/dev' ); $totalTraffic = ; // 遍历每一行,除了前两行(标题和汇总行) foreach ( $stats as $lineNum $line ) { // 跳过前两行 if ( $lineNum < 2 ) { continue ; } // 使用正则表达式匹配网络接口的行并提取接收和发送的字节数 if ( preg_match ( '/^\s*(\S+):\s+(\d+)\s+(\d+)/' , $line , $matches )) { $interface = $matches ; // 网络接口名称(可能包含冒号和数字,如 eth0:0) $receiveBytes = intval ( $matches ); $transmitBytes = intval ( $matches ); // 累积接收和发送的字节数 //因为要获取前1秒的数据 $totalTraffic += $receiveBytes ; $totalTraffic += $transmitBytes ; } } // 返回总流量信息 return $totalTraffic ; } // 获取初始的所有网络接口流量信息 $prevTotalTraffic = getAllNetworkTraffic (); // 等待一秒钟 sleep ( 1 ); // 获取当前的所有网络接口流量信息 $currTotalTraffic = getAllNetworkTraffic (); // 检查是否成功获取了流量信息 if ( $prevTotalTraffic && $currTotalTraffic ) { // 计算接收和发送的字节差异 $totalReceiveDiff = $currTotalTraffic - $prevTotalTraffic ; $totalTransmitDiff = $currTotalTraffic - $prevTotalTraffic ; // 将字节差异转换为 KB/s(千字节每秒),注意这里应该是 KBps 而不是 Kbps(因为 Kbps 通常指千比特每秒) $totalReceiveSpeedKBps = $totalReceiveDiff / 1024 ; $totalTransmitSpeedKBps = $totalTransmitDiff / 1024 ; // 输出结果 //echo "所有接口综合下行流量(接收): " . number_format($totalReceiveSpeedKBps, 2, '.', '') . " KB/s\n"; // echo "所有接口综合上行流量(发送): " . number_format($totalTransmitSpeedKBps, 2, '.', '') . " KB/s\n"; } else { // 如果无法获取流量信息,则输出错误信息 echo "无法获取所有网络接口的流量信息。\n" ; } ③代码解析 用foreach遍历同上,要注意的是,直接跳过前两行的遍历,从第三行开始 ( preg_match ( '/^\s*(\S+):\s+(\d+)\s+(\d+)/' , $line , $matches )) { $interface = $matches ; // 网络接口名称(可能包含冒号和数字,如 eth0:0) $receiveBytes = intval ( $matches ); $transmitBytes = intval ( $matches ); 正则如上图所示 ^\s*:匹配行首的任意数量的空白字符(空格、制表符等) (\S+):匹配一个或多个非空白字符,这通常代表网络接口的名称(可能包含冒号和数字,如eth0:0)。这个匹配项被捕获到$matches 中 :\s+:匹配一个冒号后跟任意数量的空白字符 (\d+):匹配一个或多个数字,这代表接收的字节数。这个匹配项被捕获到$matches 中 \s+(\d+):再次匹配任意数量的空白字符后跟一个或多个数字,这代表发送的字节数。这个匹配项被捕获到$matches 中 $totalTraffic += $receiveBytes ; $totalTraffic += $transmitBytes ; 将遍历的结果累计到变量 // 获取初始的所有网络接口流量信息 $prevTotalTraffic = getAllNetworkTraffic (); // 等待一秒钟 sleep ( 1 ); // 获取当前的所有网络接口流量信息 $currTotalTraffic = getAllNetworkTraffic (); 当前的流量 - 1秒前的流量 = 1秒内的流量 (三)硬盘信息 查询硬盘信息要关闭防跨站攻击 ①硬盘就简单很多,只需要获取根目录已经用的内存,和总内存,内存的使用率 ②代码展示 $directory = '/' ; // 获取总磁盘空间和可用磁盘空间 $totalSpace = disk_total_space ( $directory ); $freeSpace = disk_free_space ( $directory ); $totalSpaceGB = $totalSpace / ( 1024 * 1024 * 1024 ); // 或者使用 1073741824,但这种方式更清晰 $freeSpaceGB = $freeSpace / ( 1024 * 1024 * 1024 ); // 计算已用空间 $usedSpace = $totalSpace - $freeSpace ; $usedSpaceGB = $totalSpaceGB - $freeSpaceGB ; // 计算使用率(百分比) $usagePercentage = ( $usedSpace / $totalSpace ) * 100 ; ③代码解析 disk_total_space函数:获取目录所在磁盘的总空间(以字节为单位) disk_free_space函数:获取可用空间(同样以字节为单位) 将字节转换成GB,在字节上除以1024*1024*1024 (四)CPU使用率 ①CPU使用率比较复杂,但是也和上面的差不多,也是正则匹配问题 ②代码展示 function getCpuInfo ( ) { $stats = file ( '/proc/stat' ); $cpuInfo = ; if ( $cpu == '' ) { $cpu = 'total' ; } $values = preg_split ( '/\s+/' , $matches , - 1 , PREG_SPLIT_NO_EMPTY); $cpuInfo = array_map ( 'intval' , $values ); } } return $cpuInfo ; } function calculateCpuUsage ( $prev , $curr ) { $prevIdle = $prev + $prev ; // idle + iowait (Linux 2.5.41+) $currIdle = $curr + $curr ; $prevNonIdle = array_sum ( $prev ) - $prevIdle ; $currNonIdle = array_sum ( $curr ) - $currIdle ; $prevTotal = array_sum ( $prev ); $currTotal = array_sum ( $curr ); $totalDiff = $currTotal - $prevTotal ; $idleDiff = $currIdle - $prevIdle ; $cpuUsage = 100 * (( $totalDiff - $idleDiff ) / $totalDiff ); return $cpuUsage ; } // 获取初始 CPU 信息 $prevCpuInfo = getCpuInfo (); // 等待一秒(可以根据需要调整时间间隔) sleep ( 1 ); // 获取当前 CPU 信息 $currCpuInfo = getCpuInfo (); // 计算 CPU 使用率 $cpuUsage = calculateCpuUsage ( $prevCpuInfo , $currCpuInfo ); //echo "CPU Usage: " . number_format($cpuUsage, 2, '.', '') . "%\n"; ③代码讲解 使用 file('/proc/stat') 读取文件内容,每行作为数组的一个元素 遍历每行,使用正则表达式 '^cpu(\d*)\s+(.+)' 匹配 CPU 统计信息 cpu(\d*) 匹配 CPU 编号,如 cpu0, cpu1 等,没有编号的即为总体 CPU 信息(cpu) \s+(.+) 匹配该 CPU 的统计值,这些值之间用空格分隔 如果匹配成功,$cpu 变量存储 CPU 编号(或 total),$values 数组存储解析出的统计值(如用户态时间、系统态时间、空闲时间等),并将这些值转换为整数存储到 $cpuInfo 数组中。 计算空闲时间(idle)和 I/O 等待时间(iowait)的总和,这两个时间值分别位于 $prev 和 $curr 数组的索引 3 和 4 计算非空闲时间(non-idle),即总时间减去空闲时间 计算总时间的差值(totalDiff)和空闲时间的差值(idleDiff) CPU 使用率计算公式为:100 * (($totalDiff - $idleDiff) / $totalDiff) 执行流程: 调用 getCpuInfo 函数获取初始 CPU 信息($prevCpuInfo) 等待一秒(sleep(1)),以获取足够的时间间隔来观察 CPU 使用情况的变化 再次调用 getCpuInfo 函数获取当前 CPU 信息($currCpuInfo) 调用 calculateCpuUsage 函数计算 CPU 使用率
  • 热度 5
    2022-7-19 16:05
    1052 次阅读|
    0 个评论
    无论您的服务器是在Windows还是Unix上运行,这些关键性能领域都可以作为任何服务器监控策略的良好起点,跟踪这些性能指标作为性能瓶颈的指标非常重要。那么如何监控服务器性能? 1、中央处理器 (CPU) 和内存 每当服务器性能下降时,通常会怀疑服务器CPU利用率和内存资源。如果您的服务器的CPU使用率异常高或内存使用率很高(可用的可用内存空间较少),您的应用程序的性能将受到影响。 很高兴知道服务器上最消耗 CPU 和内存的进程是什么。这对于快速修复资源使用问题很重要。要测量的指标包括 CPU 进程计数、CPU 线程计数和 CPU % 中断时间。 您需要监控服务器的内存使用情况。这包括可用的可用内存、写入速率页面以释放物理内存空间等。所有这些指标都可以帮助您随时了解服务器的运行状况。 2、服务器正常运行时间 您的网站必须全天候运行并可用。服务器正常运行时间衡量系统运行的时间量。当系统可能在不知不觉中重新启动时,此指标可用于提醒您。 如果您发现预期的服务器可用性周期与服务器正常运行时间数据之间存在差异,则系统至少发生了一次故障。确认所有预计在系统发生故障时运行的计划任务是否已完成。 3、磁盘活动 磁盘活动是磁盘驱动器主动处理请求所花费的时间。必须监控几个关键指标: 磁盘繁忙时间 - 测量磁盘处于活动状态的时间百分比。如果这个值很高,这意味着你访问磁盘的请求正在堆积。 输入和输出操作 (I/OP) – 指示磁盘驱动器上的工作负载。监控此指标有助于了解您的磁盘正在承受的工作负载。 磁盘读/写——测量从磁盘读/写数据块所花费的时间。较低的值意味着性能良好。 磁盘队列长度——衡量为队列中的请求提供服务所花费的时间。为了获得最佳性能,磁盘队列长度应该最小。 请注意,监视磁盘的性能对于 I/OP 密集型任务非常重要。 4、页面文件使用 未使用或未访问的数据存储在页面文件中。超出操作系统 (OS)有限随机存取存储器 (RAM)空间的操作也会发送到页面文件中进行存储。 当您发现它的使用率很高时,这意味着系统的页面文件不足以满足您的服务器的需求。 另一个重要指标是页面交换。每当您的服务器工作内存不足时,都会保留一块磁盘空间来临时保存数据,从而释放更多空间。我们不建议页面交换。通常,这意味着您没有配置足够的内存来运行您的服务器。 请记住,页面交换是内存容量耗尽的短期解决方案。由于页面交换减少了响应时间,因此应该避免这种情况。 5、上下文切换 上下文切换是一个密集的过程。它发生在内核(计算机操作系统核心的计算机程序)将处理器从一个进程或线程切换到另一个时。每次发生上下文切换时都会使用 CPU 资源。所以当发生大范围的上下文切换时,会占用越来越多重要的 CPU 资源。 这是由运行多个繁忙进程或应用程序错误导致的,这些错误会增加上下文切换的次数。服务器上上下文切换的突然增加可能表明存在问题。因此,监视上下文切换对于服务​​器的性能至关重要。 6、时间同步 同一网络上共享文件或相互通信的系统具有有时限的活动。那么,想象一下系统时钟是否不同步?结果可能是灾难性的。 不准确的时钟可能会导致数据被覆盖或产生版本冲突。更糟糕的是,它可能导致程序无法正常运行。始终根据参考时钟监控系统时钟偏移。 7、处理用法 句柄是指应用程序引用的资源。在您的服务器上运行的应用程序请求和接收资源使用它们,然后将它们返回给操作系统。有时,由于程序错误,应用程序“忘记”在使用后返回句柄。这是句柄泄漏。 请记住,服务器上的资源是有限的。随着时间的推移,重复的句柄泄漏可能会“耗尽”服务器,从而导致服务器的性能下降。随着时间的推移密切监控和处理使用情况。如果打开句柄的数量急剧或持续增加,这可能意味着句柄泄漏。 您需要调查并确定罪魁祸首。您可以终止此类进程或修补程序。 8、过程活动 可能存在应用程序创建新进程而不停止先前启动的进程的情况。跨这些进程的处理和多任务处理会给您的服务器带来负担。 结果,您的服务器性能将受到严重影响。确保应用程序正确运行并正确退出。为此,您需要跟踪和监控服务器上的所有流程活动。 9、网络流量 网络活动监控对于衡量服务器性能至关重要。每个网络接口都提供网络活动负载的指示。如果带宽使用量接近网络接口的最大速度,这可能表明存在瓶颈。 通过持续监控网卡上的输入和输出 (I/O)活动,您可以发现可能的硬件故障或过载。您还可以规划硬件要求以确保最佳服务器性能。 10、TCP 活动 您的应用程序是面向连接的。他们使用TCP作为传输协议。HTTP、SQL、SMTP 在下面使用 TCP。如果 TCP 层性能下降,应用程序的性能也会下降。 有几个重要的指标有助于监控 TCP: 进出服务器的连接速率有助于指示服务器工作负载。 服务器上的连接断开数。高数字可能表明存在问题。 重传百分比——当服务器没有收到来自客户端的确认时发生重传。超时后,服务器必须再次发送传输。为确保良好的 TCP 性能,请尽量减少重传。请记住,重复重传可能会导致吞吐量严重下降。 11、操作系统日志文件 监控服务器运行状况的最常用方法可能是操作系统日志,因为它们包含错误详细信息、崩溃和其他类型的异常,可帮助您解决任何问题。 虽然Windows提供系统、安全和应用程序日志文件,但Unix将系统日志和 cron 日志文件存储在 /var/log 目录中。定期对日志事件进行监控、分析和警报有助于提醒您注意任何服务器异常。