简介
一种简易的监控进程的CPU、内存、线程数、句柄数的办法,使用shell脚本实现监控,Excel实现数据分析。
1.程序
#!/bin/bash
echo 这是一个简单的监控Linux服务器信息的程序
echo " "
echo 提示:
echo 输入e可以退出程序,输入h获取更多帮助
echo " "
echo "菜单如下: "
PS3="请选择模式,退出输入e,帮助输入h:"
select menu in 有组件名称 有进程号 服务器最大CPU 单个进程可打开最大文件数 进程信息 帮助 退出
do
case $REPLY in
1)
echo " "
echo 显示参数:CPU、内存、进程号、句柄数、线程数
read -t 30 -p "请在30秒内输入组件名称:" pidname
echo $pidname 组件包含的进程如下:
pids=$(ps -aux | grep $pidname|awk '{printf "%-10s\t %-10s\n", $1,$2}'|grep root|awk '{print $2}')
echo $pids
read -t 30 -p "请在30秒内输入你想要监控的进程号:" PID
read -t 30 -p "请在30秒内输入你想要监控的次数:" maxnum
read -t 30 -p "请在30秒内输入监控的时间间隔:" interval
Date=$(date "+%Y-%m-%d %H:%M:%S" )
LOG="/home/$pidname-$PID-$Date.csv"
#监控日志存储位置
sleep 5
#Delete existing files
if [ -f "$LOG" ];then
rm "$LOG"
fi
echo "PID,day,time,VmRSS,Threads,FD,%CPU" > "$LOG"
echo " "
echo 进程号:$PID 监控次数:$maxnum 监控间隔:$interval
echo 监控参数:CPU、内存、进程号、句柄数、线程数
echo 生成文件名为:$pidname-$PID-$Date.csv
echo " "
echo 监控数据如下
printf "%-10s %-10s %-25s %-10s %-10s %-10s %-10s\n" num PID Date VmRSS Threads FD %CPU
for ((num=1;num<=$maxnum;num++))
do
#时间
Date=$(date "+%Y-%m-%d,%H:%M:%S" )
#cpu
cpu=$(top -b -d 1 -n 1 -p $PID|sed -n '8p'|awk '{print $9}')
#内存
VmRSS=$(cat /proc/$PID/status | grep VmRSS |awk '{print $2}')
#线程数
Threads=$(cat /proc/$PID/status | grep Threads|awk '{print $2}')
#句柄数
FD=$(lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr|grep "\<$PID\>$"|awk '{print $1}')
printf "%-10s %-10s %-25s %-10s %-10s %-10s %-10s\n" $num $PID $Date $VmRSS $Threads $FD $cpu
echo "$PID,$Date,$VmRSS,$Threads,$FD,$cpu" >> "$LOG"
sleep $interval
done
;;
2)
echo 显示参数:CPU、内存、进程号、句柄数、线程数
read -t 30 -p "请在30秒内输入你想要监控的进程号:" PID
read -t 30 -p "请在30秒内输入你想要监控的次数:" maxnum
read -t 30 -p "请在30秒内输入监控的时间间隔:" interval
Date=$(date "+%Y-%m-%d %H:%M:%S" )
LOG="/home/$PID-$Date.csv"
#监控日志存储位置
sleep 5
#Delete existing files
if [ -f "$LOG" ];then
rm "$LOG"
fi
echo "PID,day,time,VmRSS,Threads,FD,%CPU" > "$LOG"
echo " "
echo 进程号:$PID 监控次数:$maxnum 监控间隔:$interval
echo 监控参数:CPU、内存、进程号、句柄数、线程数
echo 生成文件名为:$PID-$Date.csv
echo " "
echo 监控数据如下
printf "%-10s %-10s %-25s %-10s %-10s %-10s %-10s\n" num PID Date VmRSS Threads FD %CPU
for ((num=1;num<=$maxnum;num++))
do
#时间
Date=$(date "+%Y-%m-%d,%H:%M:%S" )
#cpu
cpu=$(top -b -d 1 -n 1 -p $PID|sed -n '8p'|awk '{print $9}')
#内存
VmRSS=$(cat /proc/$PID/status | grep VmRSS |awk '{print $2}')
#线程数
Threads=$(cat /proc/$PID/status | grep Threads|awk '{print $2}')
#句柄数
FD=$(lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr|grep "\<$PID\>$"|awk '{print $1}')
printf "%-10s %-10s %-25s %-10s %-10s %-10s %-10s\n" $num $PID $Date $VmRSS $Threads $FD $cpu
echo "$PID,$Date,$VmRSS,$Threads,$FD,$cpu" >> "$LOG"
sleep $interval
done
;;
3)
maxcpu=$(cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l)
echo " "
echo "服务器最大CPU:$maxcpu 00%"|awk -v FS=" " -v OFS="" '{print $1,$2}'
;;
4)
maxfd=$(ulimit -n)
echo " "
echo "单个进程可打开最大文件数:$maxfd"
;;
5)
#Delete existing files
if [ -f "threadinfo.txt" ];then
rm "threadinfo.txt"
fi
sleep 3
read -t 30 -p "请在30秒内输入你想要监控的进程号:" PID
echo " "
echo 进程$PID 相关线程情况如下
ps -T -p $PID >>threadinfo.txt
awk '{printf "%-10s\t %-10s\t %-10s\t%-10s\t%-10s\t%-10s\n", NR,$1,$2,$3,$4,$5}' threadinfo.txt
;;
h)
echo " "
echo "帮助:"
echo "1.监控相应参数生成了csv文件,直接打开csv文件即可对数据进行分析"
echo "2.这只是一个演示程序,需要定制更多功能,请联系Sunyuelune"
echo "感谢使用"
;;
e)
echo " "
echo "您已退出,欢迎下次使用"
exit 2
;;
*)
echo no this number,please reselect
echo $menu
esac
done
2.执行
使用ftp文件上传工具,将脚本上传到服务器
使用ls命令查看当前路径下的文件,绿色为可执行文件,使用“./文件”的方式执行,sh文件只需要将其权限改为可执行(chmod 777 文件),无需手动编译。
3.数据处理分析
用Excel打开上述处理后的csv文件,将数据粘贴到“进程占用服务器资源分析模板.xlsx”的原始数据sheet页中,查看处理数据sheet页,已有分析结果。
4.分析参考
4.1 内存和CPU
用top命令监控系统。启动一个高负载的进程,发现cpu的占用比例常常显示120%以上。
问: 对于多线程程序而言,如果线程可以占据多个cpu core的话,那么top命令看到的cpu占用经常比例超过100%属于正常情况吗?
(
https://bbs.csdn.net/topics/390472741
)
Linux 的CPU占用率是按照单核心计算的,如果该进程支持多线程,就可以占用多个核心,单个进程超过100%也是很正常的事。但如果服务器本身没什么负载,单进程或很多进程CPU占用率超过100%就需要查看原因了。
top -b -d 1 -n 1 |grep -E $PID执行结果解释:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
29376 root 20 0 17824 816 620 S 0 0 01:41.2 wrapper
各参数:
PID:进程的ID
USER:进程所有者
PR:进程的优先级别,越小越优先被执行
NInice:值
VIRT:进程占用的虚拟内存
RES:进程占用的物理内存
SHR:进程使用的共享内存
S:进程的状态。S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负数
%CPU:进程占用CPU的使用率
%MEM:进程使用的物理内存和总内存的百分比
TIME+:该进程启动后占用的总的CPU时间,即占用CPU使用时间的累加值。
COMMAND:进程启动命令名称
4.2进程与线程
4.2.1 进程概念
进程是表示资源分配的基本单位,又是调度运行的基本单位。例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格、内存空间、磁盘 空间、I/O设备等。然后,把该进程放人进程的就绪队列。进程调度程序选中它,为它分配CPU以及其它有关资源,该进程才真正运行。所以,进程是系统中的 并发执行的单位。
在Mac、Windows NT等采用微内核结构的操作系统中,进程的功能发生了变化:它只是资源分配的单位,而不再是调度运行的单位。在微内核系统中,真正调度运行的基本单位是线程。因此,实现并发功能的单位是线程。
4.2.2线程概念
线程是进程中执行运算的最小单位,亦即执行处理机调度的基本单位。如果把进程理解为在逻辑上操作系统所完成的任务,那么线程表示完成该任务的许多可能的子任务之一。例如,假 设用户启动了一个窗口中的数据库应用程序,操作系统就将对数据库的调用表示为一个进程。假设用户要从数据库中产生一份工资单报表,并传到一个文件中,这是 一个子任务;在产生工资单报表的过程中,用户又可以输人数据库查询请求,这又是一个子任务。这样,操作系统则把每一个请求――工资单报表和新输人的数据查 询表示为数据库进程中的独立的线程。
线程可以在处理器上独立调度执行,这样,在多处理器环境下就允许几个线程各自在单独处理器上进行。操作系统提供线程就是为了方便而有效地实现这种并发性。
(1) 一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
(2) 资源分配给进程,同一进程的所有线程共享该进程的所有资源。
(3) 处理机分给线程,即真正在处理机上运行的是线程。
(4) 线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
——————— 本文来自 思考v 的CSDN 博客 ,全文地址请点击:
https://blog.csdn.net/xiegh2014/article/details/79080061?utm_source=copy
4.3句柄数
在操作系统层面上,文件操作也有类似于FILE的一个概念,在Linux里,这叫做文件描述符(File Descriptor),而在Windows里,叫做句柄(Handle)(以下在没有歧义的时候统称为句柄)。用户通过某个函数打开文件以获得句柄,此 后用户操纵文件皆通过该句柄进行。
设计这么一个句柄的原因在于句柄可以防止用户随意读写操作系统内核的文件对象。无论是Linux还是Windows,文件句柄总是和内核的文件对象相关联的,但如何关联细节用户并不可见。内核可以通过句柄来计算出内核里文件对象的地址,但此能力并不对用户开放。
http://www.blogjava.net/shijian/archive/2012/04/06/373463.html