调研背景
为满足公司对现网多台服务器进行性能监控,并输出性能监控图,特对几款监控软件进行调研。目前大多数监控软件都要求在服务器上安装相应的监控软件采集数据再进行监控图输出,而公司考虑到业务的稳定性,不能在服务器上安装监控软件。所以在此我重点对RRDtool这款监控绘图工具进行调研,利用shell脚本在服务器上进行监控数据采集,集中传输到另外一个专用于处理监控数据并输出监控图的服务器上,利用rrdtool进行绘图,满足公司对性能监控的要求。
工具介绍
RRDtool 代表 “Round Robin Database tool” ,作者同时也是 MRTG 软件的发明人。许多监控软件如MRTG、Cacti等都是调用RRDtool来进行绘图的。
官方站点位于http://oss.oetiker.ch/rrdtool/ 。 所谓的“Round Robin” 其实是一种存储数据的方式,使用固定大小的空间来存储数据,并有一个指针指向最新的数据的位置。我们可以把用于存储数据的数据库的空间看成一个圆,上面有很多刻度。这些刻度所在的位置就代表用于存储数据的地方。所谓指针,可以认为是从圆心指向这些刻度的一条直线。指针会随着数据的读写自动移动。要注意的是,这个圆没有起点和终点,所以指针可以一直移动,而不用担心到达终点后就无法前进的问题。在一段时间后,当所有的空间都存满了数据,就又从头开始存放。这样整个存储空间的大小就是一个固定的数值。RRDtool 就是使用类似的方式来存放数据的工具。
RRDtool的特点:
· 首先 RRDtool 存储数据,扮演了一个后台工具的角色。但同时 RRDtool 又允许创建图表,这使得RRDtool看起来又像是前端工具。其他的数据库只能存储数据,不能创建图表。
· RRDtool 的每个 rrd 文件的大小是固定的,而普通的数据库文件的大小是随着时间而增加的。
· 其他数据库只是被动的接受数据, RRDtool 可以对收到的数据进行计算,例如前后两个数据的变化程度(rate of change),并存储该结果。
· RRDtool 要求定时获取数据,其他数据库则没有该要求。如果在一个时间间隔内(heartbeat)没有收到值,则会用 UNKN (unknow)代替,其他数据库则不会这样。
工具安装
1.下载RRDtool
cd
wget http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.4.8.tar.gz
2.安装RRDtool
#请确保已安装了相关的依赖包:zlib libxml2 libxml2-devel glib2 glib2-devel libpng freetype libart_lgpl pango-devel perl-CPAN
#执行以下命令:
BUILD_DIR=/tmp/rrdbuild
INSTALL_DIR=/usr/local/rrdtool-1.4.8
mkdir -p $BUILD_DIR
mv rrdtool-1.4.8.tar.gz $ BUILD_DIR
cd $BUILD_DIR
tar zxvf rrdtool-1.4.8.tar.gz
cd rrdtool-1.4.8
./configure --prefix=$INSTALL_DIR && make && make install
#安装完成后测试,若输出下图表示安装成功:
/usr/local/rrdtool-1.4.8/bin/rrdtool
工具配置
1.前期规划
A.监测对象:170.155服务器a.ip连接数(connect) b.cpu平均使用率(cpu) c.15分钟系统平均负载(load) d.内存使用率(memory) e.I/O wait的使用率(iowait)
D.数据文件:采用1个rrd文件保存单个服务器所有监控对象的数据,并以服务器的IP来命名,eg. 170-155.rrd
B.数据获取:利用shell来获取监测对象的数据
C.监测频率:15分钟监测一次,监测频率是指多久获取一次监测对象的数据
e.统计频率:15分钟,1小时,1天,统计频率是指利用监测数据来统计不同时间段内监测对象的平均/最大/最小等的值,统计方式依据用户设定
E.绘图方式:曲线
F.脚本规划:a.rrd_create.sh(创建rrd文件) b.rrd_update.sh(获取监控数据并更新rrd文件) c.rrd_graph.sh(绘图)
#注意:
#此处监测对象a采用使用率是方便在同一张图片上显示4个监测对象。
#此处为测试时的规划,后期在正式使用时,将监测多台现网服务器的监测对象,将数据传输到170.155服务器后再进行绘图。
#此次的监测频率为测试时的规划,后期在正式使用时,将依据实际情况进行调整。
2.rrd脚本
#创建数据保存目录:
mkdir -p /usr/local/rrdtool-1.4.8/data/170-155
#创建以下脚本:
rrd_create.sh
#########################################################################
#!/bin/bash #创建一个rrd rrdhome="/usr/local/rrdtool-1.4.8" datadir="$rrdhome/data/170-155" tooldir="$rrdhome/bin" rrdname="170_155.rrd" step="900" success="Success to create $rrdname." error="Error to create $rrdname." #创建rrd文件,依据step=900秒(即15分钟)进行1/4/96(15分钟/1小时/1天)分别进行统计平均值和最大值,并分别保存672/720/365个(1周/1月/1年)数据。 #以下数据都以百分比后的值表示,方便在同一张图上显示多个监控对象的曲线图。 #--step :就是 RRDtool “期望” 每隔多长时间就收到一个值. #DS格式:DS申明:存放脚本的结果的变量名:DS类型:1200是heartbeat:0是最小值:655350是最大值 #DST共有COUNTER、GUAGE、DERIVE、ABSOLUTE、COMPUTE 5种。最大和最小值可以用U代替,表示不限制 #RRA用于指定数据如何存放。我们可以把一个RRA看成一个表,各自保存不同的统计结果。 #格式:RRA申明:统计方式:0.5表示一个统计值中的若被用于统计的数据超过0.5倍为UNKNOWN,则统计值为UNKNOWN:1表示几个值用于统计:672表示保存几个值 #统计方式有AVERAGE,MAX,MIN,LAST。 createrrd(){ $tooldir/rrdtool create ${rrdname} --step ${step} \ DS:connect:GAUGE:1200:0:655350 \ DS:cpu:GAUGE:1200:0:100 \ DS:load:GAUGE:1200:0:100 \ DS:memory:GAUGE:1200:0:100 \ DS:iowait:GAUGE:1200:0:100 \ RRA:AVERAGE:0.5:1:672 \ RRA:AVERAGE:0.5:4:720 \ RRA:AVERAGE:0.5:96:365 \ RRA:MAX:0.5:1:672 \ RRA:MAX:0.5:6:720 \ RRA:MAX:0.5:144:365 [ "$?" == 0 ] && return 0 || return 1 } cd $datadir if [ ! -f ${rrdname} ]; then
createrrd
else
read -p "$datadir目录下已存在该文件。删除重建该文件请输入数字1,其他输入将退出:" todo
if [ "$todo" == "1" ] ;then
rm -rf $datadir/$rrdnamecreaterrd
exit 0
fi
exit 1
fi#########################################################################
#方法1:放置于crontab中15分钟执行一次。使用命令crontab -e添加以下数据:
*/15 * * * * /usr/local/rrdtool-1.4.8/data/170-155/rrd_update.sh>/dev/null 2>&1
rrd_update.sh脚本如下:
#########################################################################
#!/bin/bash #更新rrd数据库的数据。请将此脚本放置于crontab内,15分钟执行一次。 rrdhome="/usr/local/rrdtool-1.4.8" datadir="$rrdhome/data/170-155" tooldir="$rrdhome/bin" rrdname="170_155.rrd" #maxConnectNum="65535" cd $datadir if [ -f ${rrdname} ]; then #ip连接率 ##获取ip连接数 ##connected=`cat /proc/sys/net/netfilter/nf_conntrack_count` ##connected=`cat /proc/sys/net/ipv4/netfilter/ip_conntrack_count` ##计算出ip连接率 ##connect=$((${connected}*100/${maxConnectNum})) ##connect=$(echo "${connected}*100/${maxConnectNum}"|bc) #获取ip连接数 connect=`cat /proc/sys/net/netfilter/nf_conntrack_count` #cpu的使用率 ##获取cpu空闲率 cpu_free=`top -b -n 1| sed -n '1,5p'|grep Cpu|awk -F "" '{print $5}'|awk -F "%" '{print $1}'` ##计算出cpu的使用率 cpu=$(echo "100-${cpu_free}"|bc) #load系统的负载率 ##获取15分钟内的平均负载 loadaverage=`uptime|awk -F "," '{print $6}'` ##获取cpu的核芯数量 cpunum=`grep 'model name' /proc/cpuinfo |wc -l` ##计算系统的负载率load=$(echo "${loadaverage}*100/${cpunum}"|bc) #memory的使用率 ##memory的总量 memory_total=`free -t|grep Mem|awk -F "" '{print $2}'` memory_use=`free -t|grep 'buffers/cache'|awk -F "" '{print $3}'` memory=$(echo "${memory_use}*100/${memory_total}"|bc) #iowait率 iowait=`sar -p 3 1|sed -n '5p'|awk -F "" '{print $6}'` #更新rrdtool的数据 ${tooldir}/rrdtool update ${rrdname} N:${connect}:${cpu}:${load}:${memory}:${iowait} #调用绘图程序。将绘图与数据更新分开是因为后期部署时,数据更新与绘图在不同的服务器上。
sh $datadir/rrd_graph.sh
exit 0
else
echo "文件$datadir/$rrdname不存在,请先创建$rrdname文件"
exit 1
fi#########################################################################
#方法2:脚本运行后不退出,一直运行,rrd_update.sh脚本如下:
#########################################################################
#!/bin/bash #更新rrd数据库的数据。请将此脚本放置于crontab内,15分钟执行一次。 rrdhome="/usr/local/rrdtool-1.4.8" datadir="$rrdhome/data/170-155" tooldir="$rrdhome/bin" rrdname="170_155.rrd" #maxConnectNum="65535" cd $datadir if [ -f ${rrdname} ]; then do #ip连接率 ##获取ip连接数 ##connected=`cat /proc/sys/net/netfilter/nf_conntrack_count` ##connected=`cat /proc/sys/net/ipv4/netfilter/ip_conntrack_count` ##计算出ip连接率 ##connect=$((${connected}*100/${maxConnectNum})) ##connect=$(echo "${connected}*100/${maxConnectNum}"|bc) #获取ip连接数 connect=`cat /proc/sys/net/netfilter/nf_conntrack_count` #cpu的使用率 ##获取cpu空闲率 cpu_free=`top -b -n 1| sed -n '1,5p'|grep Cpu|awk -F "" '{print $5}'|awk -F "%" '{print $1}'` ##计算出cpu的使用率 cpu=$(echo "100-${cpu_free}"|bc) #load系统的负载率 ##获取15分钟内的平均负载 loadaverage=`uptime|awk -F "," '{print $6}'` ##获取cpu的核芯数量 cpunum=`grep 'model name' /proc/cpuinfo |wc -l` ##计算系统的负载率load=$(echo "${loadaverage}*100/${cpunum}"|bc) #memory的使用率 ##memory的总量 memory_total=`free -t|grep Mem|awk -F "" '{print $2}'` memory_use=`free -t|grep 'buffers/cache'|awk -F "" '{print $3}'` memory=$(echo "${memory_use}*100/${memory_total}"|bc) #iowait率 iowait=`sar -p 3 1|sed -n '5p'|awk -F "" '{print $6}'` #更新rrdtool的数据 ${tooldir}/rrdtool update ${rrdname} N:${connect}:${cpu}:${load}:${memory}:${iowait} #调用绘图程序。将绘图与数据更新分开是因为后期部署时,数据更新与绘图在不同的服务器上。 sh $datadir/rrd_graph.sh #休眠15分钟 sleep 900 done
else
echo "文件$datadir/$rrdname不存在,请先创建$rrdname文件"
exit 1
fi#########################################################################
rrd_graph.sh
#########################################################################
#!/bin/bash #执行绘图 rrdhome="/usr/local/rrdtool-1.4.8" datadir="$rrdhome/data/170-155" tooldir="$rrdhome/bin" rrdname="170_155.rrd" #绘制图片的名称 pngname="170_155.png" #绘图时用的开始时间 starttime=`date -d "-7 day" +%s` #绘图时图片的上标题 title="170.155 一周的系统性能监控" #绘图时图片的左标题 vtitle="使用率(%)" #系统允许的最大IP连接数 maxConnect="65535" cd $datadir ####绘制系统性能监控图 #--start:设定绘图的开始时间 #--width/--height:设定图表的大小,即X、Y轴围起来的范围(不是图片的大小) #-t:设定上方横向的标题 #-v:设定左侧纵向的标题 #DEF:定义数据源,格式--》DEF:自定义名称=rrd数据库文件:DS名称:DS的类型 #CDEF:v1=t1,$maxConnect,/ 将实际的IP连接数转换成IP连接率 #COMMENT就是用来输出一些字符串。 #GPRINT 就是在图表的下方输出最大值、最小值、平均值等 #绘出监控图,格式--》类型:DEF名称:颜色:显示的名称:绘图方式(STACK表示在前一个的基础上绘图) ${tooldir}/rrdtool graph ${pngname} \ --start $starttime \ --width 1090 --height 546 \ -t "$title" \ -v "$vtitle" \ DEF:t1=${rrdname}:connect:AVERAGE \ DEF:t2=${rrdname}:cpu:AVERAGE \ DEF:t3=${rrdname}:load:AVERAGE \ DEF:t4=${rrdname}:memory:AVERAGE \ DEF:t5=${rrdname}:iowait:AVERAGE \ CDEF:v1=t1,$maxConnect,/ \ COMMENT:" \n" \ COMMENT:'监控项:--------------当前值-----------平均值-----------最大值-----------' \ COMMENT:" \n" \ LINE1:v1#00FF00:"IP Connect" \ GPRINT:t1:LAST:%13.0lf \ GPRINT:t1:AVERAGE:%13.0lf \ GPRINT:t1:MAX:%13.0lf \ COMMENT:" \n" \ LINE2:t2#808080:"CPU Used":STACK \ GPRINT:t2:LAST:%13.2lf \ GPRINT:t2:AVERAGE:%13.2lf \ GPRINT:t2:MAX:%13.2lf \ COMMENT:" \n" \ LINE3:t3#FF0000:"System Load" \ GPRINT:t3:LAST:%13.2lf \ GPRINT:t3:AVERAGE:%13.2lf \ GPRINT:t3:MAX:%13.2lf \ COMMENT:" \n" \ LINE2:t4#F0FF0F:"Memory Used" \ GPRINT:t4:LAST:%13.2lf \ GPRINT:t4:AVERAGE:%13.2lf \ GPRINT:t4:MAX:%13.2lf \ COMMENT:" \n" \ LINE1:t5#4B0082:"iowait Used" \ GPRINT:t5:LAST:%13.2lf \ GPRINT:t5:AVERAGE:%13.2lf \ GPRINT:t5:MAX:%13.2lf \ COMMENT:" \n" \ COMMENT:"上次更新\: $(date '+%Y-%m-%d %H\:%M\:%S' -r $rrdname)"
#修改脚本的权限
chmod 750 /usr/local/rrdtool-1.4.8/data/170-155/*.sh
3.脚本部署
#创建rrd文件
/usr/local/rrdtool-1.4.8/data/170-155/rrd_create.sh
#cron设置
*/15 * * * * /usr/local/rrdtool-1.4.8/data/170-155/rrd_update.sh>/dev/null 2>&1
4.绘图结果
#结果说明:
#由于是在170.155上测试,在此服务器上基本没有程序在运行,各项监控参数的使用率接近0,所以看上去不明显,在实际生产环境中应该不会存在此情况。