背景

相信每一位运维人员手里都掌握着不少的服务器,少则几十台,多则成百上千,线上服务器跑的服务五花八门,每台服务器资源消耗都不同,如果能够对资源消耗较高的进程实现自动发现监控将对排查问题有很大的帮助。

实现

导出数据

1.在zabbix客户端下新建一个专门存放脚本的文件,我们在一个目录下创建下面的脚本文件。

1
2
1.mkdir -p /opt/zabbix_agent/scripts
2.vi top.sh

2.使用 top 命令获取服务器当前运行状态,将结果重定向到一个文本文件中。
cat top.sh

1
2
#!/bin/sh
top -n -b 1 > /tmp/top.txt

注: 该命令的意思是执行一次top命令并将结果重定向到top.txt文件中去

创建定时任务

1.将该命令添加到zabbix用户的计划任务中去,每分钟执行一次并清空,使文本中保证一份数据。

1
2
1.crontab -e
2.*/1 * * * * /opt/zabbix_agent/scripts/top.sh > /dev/null

放进去之后在tmp目录下会生成一个top.txt文件

1
1.head -10 /tmp/top.txt

获取进程名

1.获取到数据后,对数据进行处理,获取占用资源高的进程名
cat check_process.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
TABLESPACE=`tail -n +8 /tmp/top.txt|awk '{a[$NF]+=$6}END{for(k in a)print a[k]/1024,k}'|sort -gr|head -10|cut -d" " -f2`
COUNT=`echo "$TABLESPACE" |wc -l`
INDEX=0
echo '{"data":['
echo "$TABLESPACE" | while read LINE; do
echo -n '{"{#PROCESSNAME}":"'$LINE'"}'
INDEX=`expr $INDEX + 1`
if [ $INDEX -lt $COUNT ]; then
echo ','
fi
done
echo ']}'

注: 最关键的是tail -n +8 /tmp/top.txt|awk ‘{a[NF]+=NF]+=6}END{for(k in a)print a[k]/1024,k}’|sort -gr|head -10|cut -d” ” -f2这条命令:这条命令的意思是从top.txt文件中取出从第八行到末尾行的数据,然后使用awk对这些数据进行累加,效果是以最后一列为关键字,每个关键字对应的第6列的数值进行累加,输出第六列数据的累加结果和最后一列数据,然后使用sort进行排序,注意这里的参数是使用-gr而不是使用-nr是因为获取到的第六列的值是以KB为单位的,假如某进程占用内存大于10G的话,将会使用科学记数法计数,sort -nr参数无法对科学记数法进行计数,需要将参数改成-gr才行,其中的-r是进行反向排序,同时为了防止zabbix获取到该值是科学记数法获取的值从而无法识别,先将该值/1024将单位变成MB,当zabbix获取到数据后再_1024_1024将该值还原成BYTE单位。head -10是取出占用内存最大的十个进程,然后使用cut对数据进行切分,获得十个进程的进程名。

将获取到的十个进程名进行json格式化的输出,输出结果如下:
./check_process.sh

1
2
3
4
5
6
7
8
9
10
11
12
{"data":[
{"{#PROCESSNAME}":"hdbprepr+"},
{"{#PROCESSNAME}":"hdbwebdi+"},
{"{#PROCESSNAME}":"hdbcompi+"},
{"{#PROCESSNAME}":"gnome-sh+"},
{"{#PROCESSNAME}":"corosync"},
{"{#PROCESSNAME}":"hdb.sapE+"},
{"{#PROCESSNAME}":"gnome-se+"},
{"{#PROCESSNAME}":"Xorg"},
{"{#PROCESSNAME}":"sapstart+"},
{"{#PROCESSNAME}":"pengine"}]}

注:本例是以 RES 作为标准衡量资源消耗,可通过其他指标来监控。

获取资源消耗

获取某个进程占用的cpu和内存资源情况
cat process_monitor.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/sh
process=$1
name=$2
case $2 in
mem)
echo "`tail -n +8 /tmp/top.txt|awk '{a[$NF]+=$6}END{for(k in a)print a[k]/1024,k}'|grep "$process"|cut -d" " -f1`"
;;
cpu)
echo "`tail -n +8 /tmp/top.txt|awk '{a[$NF]+=$9}END{for(k in a)print a[k],k}'|grep "$process"|cut -d" " -f1`"
;;
*)
echo "Error input:"
;;
esac
exit 0

在本地测试一下取值:
在这里插入图片描述
在这里插入图片描述
能获取到值了之后就需要在zabbix_agentd.conf里面配置相应的键值来获取数据了,下面是需要添加的配置:

1
2
3
4
5
tail -3 zabbix_agentd.conf
#top_process
UserParameter=process.discovery,/opt/zabbix_agent/scripts/check_process.sh
UserParameter=process.resource[*],/opt/zabbix_agent/scripts/process_monitor.sh $1 $2

添加该配置之后需要重启zabbix_agentd才能使配置生效,在服务端验证是否能够获取到数据了,在服务端使用zabbix_get命令来获取数据,下面是执行的结果:
[root@zabbix3 ~]# /usr/local/zabbix/bin/zabbix_get -s 192.168.4.129 -k “process.discovery”

1
2
3
4
5
6
7
8
9
10
11
12
{"data":[
{"{#PROCESSNAME}":"hdbprepr+"},
{"{#PROCESSNAME}":"hdbwebdi+"},
{"{#PROCESSNAME}":"hdbcompi+"},
{"{#PROCESSNAME}":"gnome-sh+"},
{"{#PROCESSNAME}":"corosync"},
{"{#PROCESSNAME}":"hdb.sapE+"},
{"{#PROCESSNAME}":"gnome-se+"},
{"{#PROCESSNAME}":"Xorg"},
{"{#PROCESSNAME}":"sapstart+"},
{"{#PROCESSNAME}":"pengine"}]}

上面的xxx.xxx.xxx.xxx代表的是客户端的IP地址,-k后面的参数就是刚刚我们在客户端上面添加的参数

1
2
3
4
5
$ /usr/local/zabbix/bin/zabbix_get -s xxx.xxx.xxx.xxx -k "process.resource[httpd,mem]"
20.125
$ /usr/local/zabbix/bin/zabbix_get -s xxx.xxx.xxx.xxx -k"process.resource[httpd,cpu]"
0

创建模板

在服务端测试客户端取值没有问题。接下来就需要在web端配置模板了。在配置—》模板—》创建模板里面创建一个模板,叫做Temple Top Process如下图所示:

创建一个应用集叫做top of process resource,如下图所示:

创建好后,需要添加探索规则了,新建探索规则,如下图所示:

1.这里我将时间设置为3600s因为是生产机,为了减少服务器的负荷。我们在测试的时候可以将时间写成60s。
2.在过滤器里面写上我们定义的宏
其中的键值就是我们在客户端上面配置的键值,数据更新间隔我这里设置为6分钟,就是说每间隔6分钟它就会去客户端获取占用内存最大的十个进程,可以根据需求自己设置,然后取它们的内存和cpu占用资源数据。下面就需要配置项目原形了,如下图所示:

添加完项目原型后需要配置图形原型,如下图所示:

添加好图形原形后,该模版就制作成功了,接下来将该模板添加到主机上,就能够获取到数据了。

img