使用背景
线上有多台游戏服务器,每台游戏服务器部署多个游戏服,每个游戏服会启动两个java进程,一个game_word
,一个game_db
,现在要对这些所有机器上的所有游戏服进程进行内存和CPU进行监控。
我使用的zabbix版本为3.4
游戏名,目录都为临时命名
游戏进程如下
root 2314 2310 0 10:55 pts/0 00:01:28 java -server -Xms1024m -Xmx1024m -Xmn512m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:MaxDirectMemorySize=512m -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+DisableExplicitGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -verbose:gc -Xloggc:/gamedata/mmk_game_s11/log4j2/gc/mmk_game_s11_DB_gc.log -XX:ErrorFile=/gamedata/mmk_game_s11/log4j2/error/mmk_game_s11_DB_error_%p.log -XX:HeapDumpPath=/gamedata/mmk_game_s11/log4j2/error/mmk_game_s11_DB_heapDump_%p.hprof -cp ./classes:./config/:./libs/* core.dbsrv.main.DBStartup
root 2346 2342 0 10:55 pts/0 00:00:52 java -server -Xms2632m -Xmx2632m -Xmn1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:MaxDirectMemorySize=1024m -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+DisableExplicitGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -verbose:gc -Xloggc:/gamedata/mmk_game_s11/log4j2/gc/mmk_game_s11_srvWorld0_gc.log -XX:ErrorFile=/gamedata/mmk_game_s11/log4j2/error/mmk_game_s11_srvWorld0_error_%p.log -XX:HeapDumpPath=/gamedata/mmk_game_s11/log4j2/error/mmk_game_s11_srvWorld0_heapDump_%p.hprof -Dsun.zip.disableMemoryMapping=true -javaagent:libs/classReloader.jar -cp ./classes/:./config/:./libs/:./libs/* game.seam.main.WorldStartup 0
proc.mem[<name>,<user>,<mode>,<cmdline>,<memtype>]
和proc.cpu.util[<name>,<user>,<type>,<cmdline>,<mode>,<zone>]
在zabbix3.4版本中有个proc.mem
,proc.cpu.util
有这两个key item参数,可用来对单进程的内存和cpu进行监控。
参数的相关文档如下:
以proc.mem
这个key说明
先已简单的nginx
进程为例
在10.163.46.81
使用top
查看nginx
的内存信息
在server
端,使用zabbix_get
测试key
值命令
[root@zabbix_server ~]# zabbix_get -s 10.163.46.81 -p 10050 -k "proc.mem[nginx,root]"
112234496
文档上可以得知,proc.mem
取得的默认值为VIRT
的值
再次获取一次内存信息,这次获取ngixn
内存RES
的值
[root@zabbix_server ~]# zabbix_get -s 10.163.46.81 -p 10050 -k "proc.mem[nginx,root,,,rss]"
4304896
这样就能获取单个进程的虚拟内存,物理内存值。
由于机器上只有一个name
值为nginx
的进程,所以我们在使用proc.mem
直接指定name
值即可。
但我们实际要监控的游戏进程都为java
的进程名,那要如何处理呢?
这时,就需要proc.mem
的cmdline
参数,cmdline
参数可支持正则。
cmdline
又是什么呢?
以刚才的java进程为例:
刚才java
有个进程号为2314
,打印出cmdline
值
[root@zabbix_agemt tmp]# cat /proc/2314/cmdline
java-server-Xms1024m-Xmx1024m-Xmn512m-XX:MetaspaceSize=128m-XX:MaxMetaspaceSize=256m-XX:MaxDirectMemorySize=512m-XX:+UseParallelGC-XX:+UseParallelOldGC-XX:+DisableExplicitGC-XX:+PrintGCDateStamps-XX:+PrintGCDetails-verbose:gc-Xloggc:/gamedata/mmk_game_s11/log4j2/gc/mmk_game_s11_DB_gc.log-XX:ErrorFile=/gamedata/mmk_game_s11/log4j2/error/mmk_game_s11_DB_error_%p.log-XX:HeapDumpPath=/gamedata/mmk_game_s11/log4j2/error/mmk_game_s11_DB_heapDump_%p.hprof-cp./classes:./config/:./libs/*core.dbsrv.main.DBStartup
所以此处cmdline
取每个服的特有值mmk_game_s11_DB
使用proc.mem
打印出这个服的db
的内存值
[root@zabbix_server tmp]# zabbix_get -s 10.163.46.81 -p 10050 -k "proc.mem[,root,,mmk_game_s1_srvWorld0,rss]"
608288768
这样就取到了这个游戏服单个进程的RES
内存值
这是手动获取单个服的DB
内存,为了后续能使用自主发现功能,我们需要写个脚本,把每台机器上的游戏服名称获取出来。
编写获取游戏服的脚本
在zabbix_agent
端编写,脚本直接放在zabbix/script
中
[root@zabbix_agent zabbix]# cat script/check_porcess.sh
#!/bin/bash
## zabbix process
## date: 2017.11.27
process_dir=/gamedata
game_list=`ls ${process_dir}|grep game`
game_num=0
INDEX=0
for game in `echo ${game_list}`;do
game_world_pid=`ps aux|grep java|grep ${game}|grep srvWorld0|awk '{print $2}'`
if [ -n "${game_world_pid}" ];then
((game_num++))
fi
done
echo '{"data":['
for game in `echo ${game_list}`;do
game_world_pid=`ps aux|grep java|grep ${game}|grep srvWorld0|awk '{print $2}'`
if [ -n "${game_world_pid}" ];then
echo '{"{#PROCESSNAME}":"'${game}_srvWorld0'"},'
INDEX=`expr $INDEX + 1`
if [ $INDEX -lt ${game_num} ];then
echo '{"{#PROCESSNAME}":"'${game}_DB'"},'
else
echo '{"{#PROCESSNAME}":"'${game}_DB'"}'
fi
fi
done
echo ']}'
直接运行脚本,测试脚本是否正常。
[root@zabbix_agent zabbix]# sh script/check_porcess.sh
{"data":[
{"{#PROCESSNAME}":"mmk_game_s1_srvWorld0"},
{"{#PROCESSNAME}":"mmk_game_s1_DB"},
{"{#PROCESSNAME}":"mmk_game_s99_srvWorld0"},
{"{#PROCESSNAME}":"mmk_game_s99_DB"}
]}
修改zabbix_agent
修改配置文件以及添加配置文件
[root@zabbix_agent zabbix]# cat etc/zabbix_agentd.conf|grep -v ^#|grep -v ^$
LogFile=/tmp/zabbix_agentd.log
Server=10.163.254.250
ServerActive=10.163.254.250
Hostname=zabbix_agent
Include=/usr/local/zabbix/etc/zabbix_agentd.conf.d
UnsafeUserParameters=1
其中修改的内容就是添加最后两行信息
Include=/usr/local/zabbix/etc/zabbix_agentd.conf.d
UnsafeUserParameters=1
然后在zabbix_agentd.conf.d
添加一个新的配置文件信息
[root@zabbix_agent zabbix]# cat etc/zabbix_agentd.conf.d/java_process.conf
UserParameter=gameprocess,/usr/local/zabbix/script/check_porcess.sh
在server
端测试key
值gameprocess
是否正常
[root@zabbix_server ~]# zabbix_get -s 10.163.46.81 -p 10050 -k "gameprocess"
{"data":[
{"{#PROCESSNAME}":"mmk_game_s1_srvWorld0"},
{"{#PROCESSNAME}":"mmk_game_s1_DB"},
{"{#PROCESSNAME}":"mmk_game_s99_srvWorld0"},
{"{#PROCESSNAME}":"mmk_game_s99_DB"}
]}
脚本内容到此完成,下面开始模板创建。
创建新的模板,添加自主发现内容
创建模板
关联Template OS Linux
模板
在模板中添加discovery
此处一定要在模板中创建,而不是最顶端的那个discovery
添加一个discovery rule
在模板中添加Item prototypes
创建三个Item prototypes
,两个内存的,一个CPU的
在模板中添加Graph prototypes
至此模板已创建完成。
开始创建网络发现服务,让主机自动关联刚刚创建的模板001_process_template
添加action