Zabbix自动发现是通过(1)网络扫描或(2)代理主动发现实现监控。本文主要介绍网络扫描的发现方式,并深入介绍底层监控项的主动发现功能。

<>网络发现(Discovery)


对于网络发现最需要理解的就是工作流程,不然觉得这个发现功能很奇怪,理解之后,就觉得这个设计很合理了。而且使用起来也很正常,而大部分文章只是讲解了如何使用,官方文件简单的提到了工作流程,不小心很容易忽略。
参考文档:
https://www.zabbix.com/documentation/4.0/manual/discovery/network_discovery
<https://www.zabbix.com/documentation/4.0/manual/discovery/network_discovery>

自动发现主要是希望通过发现网络中的主机,并自动把主机添加到监控中,并关联特定的模板,实现自动监控。例如在办公网络中,希望通过Zabbix
Agent监控所有工作电脑,只需要把新安装的电脑开放防火墙10050端口,那么电脑就可以自动通过发现新机器,并开始监控。如果网络中可能存在Windows和Linux系统,就需要通过Zabbix
Agent判断自动添加的主机是Windows还是Linux。
以上这个过程需要分为两个步骤:

* 通过网络扫描制定的服务,本例为Zabbix Agent是否可以访问system.uname指标
* 发现主机之后需要执行添加的动作,这个过程由动作(Action)完成


下图为配置扫描是的方法:


扫描到网端内存在新机器时,就会出现在监控(Monitoring)->发现(Discovery)中:


如果希望把新发现的机器添加到Zabbix监控范围,就需要通过动作来实现主机添加,模板关联了。如下图所示,在配置(Configuration)->动作(Action),选择事件源为发现(Discovery)。通过创建一个新动作,配置好条件和动作实现自动添加主机功能。

工作流程如下:


如图,如果网络中有新的机器加入,Zabbix
Server扫描到了该机器的代理服务,并且满足动作的条件,则会执行添加主机的动作,并自动关联模板。如果需要分别添加Windows和Linux主机,则需要分别创建两个规则,并通过Zabbix主机发现制定的检查值(本例为system.uname指标)判断是否包含windows或者linux字样来判断是否采用特定的规则。

<>底层自动发现(Low Level Discovery)


什么叫底层发现?底层发现是相对与网络发现的,这里翻译为“底层”有点儿不好理解,“低级别”的发现也不是很合理,最好的理解是:发现监控项,相对于添加主机而言,监控项是位于主机之下的,所以有“底层发现”之说。底层发现主要是发现监控主机的监控项,并自动进行监控的一个功能。主要可以实现自动添加监控项,添加触发器,添加图,也可以添加另外的主机。通过底层发现规则自动添加的规则叫做原型。
参考文档:
https://www.zabbix.com/documentation/4.0/manual/discovery/low_level_discovery
<https://www.zabbix.com/documentation/4.0/manual/discovery/low_level_discovery>
底层发现执行需要在特定的主机之上才可以执行,而且只能通过模板来添加(添加多项,就是复制操作,需要原型来定义)。他的工作原理如下:

* 通过采集主机的特定指标,获得一个JSON对象
* 解析JSON对象,匹配原型,获得需要执行的添加项的具体内容
* 检查该模型是否已经添加,有则结束
* 添加具体的内容,如果有多项,则添加多项(监控项,触发器,图,其他主机)

下面以监控Java进程的内存使用情况为例,分析如何实现自动发现机器上运行的Java进程,并主动监控Java进程的内存使用情况,本例仅实现监控进程的内存回收时间和执行回收的次数。
监控Java进程在JDK中有一个jps工具,可以监控Java的进程名称和进程号,例如执行如下命令:
[root@upass-server scripts]# jps -l 1760 upaas-config-server-1.1.0.jar 1906
content-uauth-client-1.1-SNAPSHOT.jar 1735 upaas-eureka-server-1.1.0.jar 1831
content-uauth-service-1.1-SNAPSHOT.jar 4360
org.apache.catalina.startup.Bootstrap 22670 sun.tools.jps.Jps
例如上面系统运行了Tomcat服务和Spring Cloud的几个微服务,希望通过进程IP获得每一个进程的内存回收数据。这可以通过jstat获得。
[root@upass-server scripts]# jstat -gc 1760 S0C S1C S0U S1U EC EU OC OU MC MU
CCSC CCSU YGC YGCT FGC FGCT GCT 1536.0 6656.0 1184.0 0.0 158720.0 14280.5
70144.0 29983.1 60888.0 57833.7 7936.0 7439.1 36 53.392 3 0.318 53.711
具体指令参考:https://blog.csdn.net/wayne_2015/article/details/71159813
<https://blog.csdn.net/wayne_2015/article/details/71159813>
要实现自动发现Java进程,需要通过一个脚本实现发现,并配置到Zabbix Agent中。
发现脚本:zbx_java_discovery.sh
#!/bin/bash javaProcessList=`sudo $JAVA_HOME/bin/jps -l | grep -v Jps | grep
-v Jstat | awk '{print $1"#"$2}' | grep "^[0-9]*#[a-zA-Z].*" ` echo
"{\"data\":[" first=1 for javaProcess in $javaProcessList; do IFS='#' read -r
-a items <<< "$javaProcess"; if [ $first == 1 ]; then echo
"{\"{#JAVAPSNAME}\":\"${items[1]}\",\"{#JAVAPSPID}\":\"${items[0]}\"}"; first=0
else echo
",{\"{#JAVAPSNAME}\":\"${items[1]}\",\"{#JAVAPSPID}\":\"${items[0]}\"}"; fi
done; echo "]}";
检查Java进程内存回收的脚本: zbx_java_stat.sh
#!/bin/sh #jstat -gc $PID # S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC
YGCT FGC FGCT GCT #512.0 512.0 0.0 0.0 4416.0 1982.6 10944.0 0.0 4480.0 866.8
384.0 73.9 0 0.000 0 0.000 0.000 if [ 'YGC' == $2 ]; then pos=13 elif [ 'YGCT'
= $2 ]; then pos=14 elif [ 'FGC' == $2 ]; then pos=15 elif [ 'FGCT' == $2 ];
then pos=16 elif [ 'GCT' == $2 ]; then pos=17 else pos=0 fi sudo
$JAVA_HOME/bin/jstat -gc $1 | grep -v YGC | awk -v p=$pos '{print $p}'
把上面两个脚本添加到Zabbx agent UserParameter中:
### Option: UserParameter # User-defined parameter to monitor. There can be
several user-defined parameters. # Format: UserParameter=<key>,<shell command>
# See 'zabbix_agentd' directory for examples. # # Mandatory: no # Default: #
UserParameter= UserParameter=javaps,/etc/zabbix/scripts/zbx_java_discovery.sh
UserParameter=javastat[*],/etc/zabbix/scripts/zbx_java_stat.sh $1 $2
这样就可以通过Zabbix Agent调用脚本了。
例如,调用javaps查看java进程信息:
[zabbix@upass-server ~]$ /etc/zabbix/sbin/zabbix_agentd -c
/etc/zabbix/conf/zabbix_agentd.conf -t javaps javaps [t|{"data":[
{"{#JAVAPSNAME}":"upaas-config-server-1.1.0.jar","{#JAVAPSPID}":"1760"}
,{"{#JAVAPSNAME}":"content-uauth-client-1.1-SNAPSHOT.jar","{#JAVAPSPID}":"1906"}
,{"{#JAVAPSNAME}":"upaas-eureka-server-1.1.0.jar","{#JAVAPSPID}":"1735"}
,{"{#JAVAPSNAME}":"content-uauth-service-1.1-SNAPSHOT.jar","{#JAVAPSPID}":"1831"}
,{"{#JAVAPSNAME}":"org.apache.catalina.startup.Bootstrap","{#JAVAPSPID}":"4360"}
]}]
就可以输出底层发现要求的JSON格式了。
调用javastat就可以获得特定进程的内存回收状态了,格式为javastat[PID|YGC|YGCT|FGC|
FGCT|GCT]
[zabbix@upass-server ~]$ /etc/zabbix/sbin/zabbix_agentd -c
/etc/zabbix/conf/zabbix_agentd.conf -t javastat[1760,YGC] javastat[1760,YGC]
[t|36]
这里需要注意:

* Zabbix
Agent要求用非Root用户运行,如果java进程用其他用户,或者root用户运行,可能jps无法查询,所以需要配置zabbix用户的sudo,请参考:
https://blog.csdn.net/huangzhijie3918/article/details/51345178
<https://blog.csdn.net/huangzhijie3918/article/details/51345178>
* Zabbix Agent测试时要注意,如果不是确实配置文件位置,那么需要在执行命令时制定配置文件,才可以正确执行。
通过以上工作,zabbix agent就可以实现java进程的内存回收监控了,下面在Zabbix Server上实现自动发现监控。
流程如下:

* 创建一个监控的模板
* 在该模板上添加一个自动发现规则
* 在新添加的规则上添加监控项原型(prototype)
* 把新模板关联到部署好的主机(也可以添加到上一节中自动发现规则的自动添加模板中)
下面图示配置内容:
添加一个模板,并关联一个模板组:

在模板中添加底层自动发现(Low Level Discovery),实现自定义的java内存监控,这里需要选择采用zabbix
agent,并输入关键字(key)为前面编写的javaps命令,该命令执行zbx_java_discovery.sh脚本,获得当前进程列表的JSON数据。

在通过底层自动发现模板,添加监控项(Item)模板,实现自动监控当前运行的有效Java进程。

一共添加了5个监控项,分别获取Java年轻代内存回收次数,时间,全内存回收(FGC)次数和时间,内存回收总耗时。
经过Zabbix自动发现后,就会自动添加监控项,并开始监控,如果存在错误,会有告警提示。


注意:
如果在调试过程中发现不对劲的地方,可以通过调高日志级别,获取更多的日志信息,有助于解决问题。
下面指令调高服务器日志级别:
zabbix_server -c /usr/local/etc/zabbix_server.conf -R log_level_increase
具体文档参考:
https://www.zabbix.com/documentation/4.0/manual/concepts/server
<https://www.zabbix.com/documentation/4.0/manual/concepts/server>