您的位置:首页 > 运维架构 > Shell

如何通过shell脚本统计apache使用多少内存

2012-11-14 21:59 507 查看
很多筒子问我如何能够写出能用的shell脚本

这事其实不难,只要按照以下思路进行就行了

1 把复杂的问题简单化,模块化

2 写出每个模块的伪码

3 组装你的模块

4 写出shell code

5 测试

这事看起来很简单,做起来。。。。。 其实也不难,so easy!

大多数人都是因为害怕所以不敢开始仅次而已,所以筒子们开始吧,从现在开始就动手写你的shell吧

你会喜欢上这工作的!

我们现在就来分析需求统计apache的内存使用量

apache的内存使用量数据如何获得呢?



这事就是硬功夫了,要写shell你得多linux操作系统了解,数据得从/proc/$apachepid/smaps里面获得,对里面的字段进行统计分类来获得。



apache的pid如何获得?



[root@www conf]# ps -eo user,pid | grep '^apache' 
apache   12160 
apache   12161 
apache   12162 
apache   12163 
apache   12164 
apache   12165 
apache   12166 
apache   12167 

顺着这个思路就可以想到用awk来解决,用awk的数组就可以了



[root@www conf]# awk ' $3 ~ "kB" { sum[$1] += $2} END {for (key in sum) print key, sum[key]" kB"}'  /proc/12160/smaps Shared_Clean: 628 kB Pss: 378 kB Swap: 0 kB Shared_Dirty: 2508 kB Size: 19796 kB Private_Dirty: 152 kB Private_Clean: 0 kB Rss: 3288 kB 

apache的进程又不是一个,很多个,如何收集所有进程信息呢?



用个循环就可以了,先把apache的pid放到一个数组里面,然后在找个数组里面循环执行awk统计



APACHEPID=($(ps -eo user,pid | awk '$1~"^apache"{print $2}')) 
#设定数组变量APACHEPID并把获得apache-pid复制给这个数组 
echo "apache total process: ${#APACHEPID[@]}" 
#数组里面元素的个数,就是apache进程的总数 

for pid in ${APACHEPID[@]} 
do 
    echo $pid: 
    awk ' $3 ~ "kB" { sum[$1] += $2} END {for (key in sum) print key, sum[key]" kB"}'  /proc/$pid/smaps 
done &> /tmp/apachemem 

#在数组里面循环执行awk统计,并把结果放入到/tmp/apachemem临时文件内 

最后还可以把这个临时文件输入,如果您愿意,ok,现在这个脚本总体就是这个样子了

#!/bin/bash 
APACHEPID=($(ps -eo user,pid | awk '$1~"^apache"{print $2}')) 
echo "apache total process: ${#APACHEPID[@]}"    

for pid in ${APACHEPID[@]} 
do 
    echo $pid: 
    awk ' $3 ~ "kB" { sum[$1] += $2} END {for (key in sum) print key, sum[key]" kB"}'  /proc/$pid/smaps 
done &> /tmp/apachemem 

echo "apache total memsum:" 
awk '$3 ~ "kB" { sum[$1] += $2} END {for (key in sum) print key, sum[key]" kB"}' /tmp/apachemem 

echo "delete tmp file!" 
rm -fr /tmp/apachemem 

怎么样,简单吧!

但是这样的脚本看起来就“很挫”,我们把它变得专业点,也是大家以后养成好的编码习惯,用一种函数编程的思想去写code。

#!/bin/bash 

TMPFILE=/tmp/apachemem 
#get apache pid 
APACHEPID=($(ps -eo user,pid | awk '$1~"^apache"{print $2}')) 
echo "apache total process: ${#APACHEPID[@]}" 

#define memtotal 
memtotal() { 
    filename=$1 
    awk ' $3 ~ "kB" { sum[$1] += $2} END {for (key in sum) print key, sum[key]" kB"}'  $filename 
} 

#get every pid memtotal into tmpfile 
for pid in ${APACHEPID[@]} 
do 
    echo $pid: 
    memtotal /proc/$pid/smaps 

done &> $TMPFILE 

#get apache total memsum 
echo "apache total memsum:" 
memtotal $TMPFILE 

#delete tmpfile 
echo "delete tmp file!" 
#rm -fr /tmp/apachemem 

这里把统计的过程设置为一个函数memtotal,这样做的好处是能够提高代码的复用度,看起来也简介,后期修改直接改这个函数就可以了,不用全文修改。

下面是执行的结果

[root@www tmp]# ./apache-mem.sh  
apache total process: 8 
apache total memsum: 
Shared_Clean: 5024 kB 
Pss: 3024 kB 
Size: 158368 kB 
Shared_Dirty: 20064 kB 
Swap: 0 kB 
Private_Dirty: 1216 kB 
Private_Clean: 0 kB 
Rss: 26304 kB 
delete tmp file! 

时间有限,水平有限,这个脚本还有很多其他需要完善的地方,例如添加交互式的设计,统计哪个服务的内存由参数$1传递进去,脚本的健壮性还有待加强,算是抛砖引玉吧,请大家多交流。

最后想对shell刚入门的筒子说,只要你动手开始写shell就已经成功一半了,剩下的就是一个积累的过程。

加油!!!!你可以的!!!
本文出自 “风生水起” 博客,转载请与作者联系!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: