一种Java实现的Zabbix监控框架——Zabbix/J

Zabbix/J是一个能够将Zabbix监控整合入Java应用程序的框架,而Zabbix是一个开源的企业级分布式监控解决方案,它可以在整个基础设施中提供遥测和触发器的功能。Zabbix/J实际上是一个Java版本的Zabbix探针,它可以很方便地采集Java应用程序中的各种数据,并且可以将它们发送至Zabbix服务器,使得技术人员可以在Zabbix的前端页面上对其进行监控。

Zabbix/J的系统需求非常简单,它不需要任何形式的JMX或应用程序容器(虽然Zabbix/J也可以非常高效地使用它们)。通过一个简单的Java接口,Zabbix/J就可以获取你的Java应用程序中的数据了,而这个接口只有一个方法。如果你使用Spring框架,那么你就可以在Spring的上下文中配置Zabbix/J,当你启动你的应用程序时,应用程序容器便会实例化、配置和启动一个单例的Zabbix/J实例。

本文将会详述Zabbix/J的下载和安装方法,并且通过示例代码讲解它的使用方法。

一、环境描述

1. Zabbix Server

2. Zabbix Agent

3. Zabbix/J

  • 操作系统:同Zabbix Agent
  • IP地址:同Zabbix Agent
  • 版本:1.0.1
  • 安装方法:参照本文

4. Java环境

  • 操作系统:同Zabbix Agent
  • IP地址:同Zabbix Agent
  • JDK版本:1.7.0_60
  • IDE版本:Spring Tool Suite 3.6.3

二、下载和安装Zabbix/J

Zabbix/J的下载地址如下所示:

  1. https://codeload.github.com/michaelquigley/zabbixj/zip/dev_1_0_1

下载得到的文件名为zabbixj-dev_1_0_1.zip,解压缩至Spring Tool Suite的Workspace目录中,然后将解压得到的文件夹重命名为zabbixj-parent

打开Spring Tool Suite,点击菜单File → Import,在弹出的“Import”窗口中,选择“Existing Maven Projects”,然后点击“Next”按钮,如下图所示:

导入已有的Maven工程

进入“Import Maven Projects”窗口,点击“Browser”按钮,找到Zabbix/J的源码所在的目录路径,然后点击“Finish”按钮,如下图所示:

导入Maven项目

至此,Zabbix/J的源码便已经成功导入Spring Tool Suite中了,待Maven同步完所有的依赖包之后,便可以运行示例程序了。

三、系统架构

Zabbix/J可以和Zabbix完美地协同合作,它们组成的系统架构如下图所示:

Zabbix监控系统架构

在上图中,深蓝色部分是Zabbix的原生组件,黄色部分是Zabbix/J的相关组件,Zabbix的原生组件和Zabbix/J的相关组件是可以完美地互相操作的,下文会通过示例程序证明这一点。

我们可以将系统监控分为三个层面:

  • 第一层:基础设施监控,它包含对服务器的硬件、网络、操作系统等的监控,通常Zabbix的原生监控项就可以满足此类监控需求。

  • 第二层:应用软件/中间件监控,例如对JVM、JBoss、MySQL、Redis等业务系统用到的软件进行监控,通常需要利用Zabbix的ODBC、JMX等支持功能进行二次开发才能满足此类监控需求,另外使用Zabbix/J进行二次开发也可以满足此类监控需求。

  • 第三层:业务系统监控,使用Zabbix/J进行二次开发,监控业务系统内的一些关键数据(例如,订单量、在线用户数量等等)。

如果仅仅使用Zabbix的基本功能,那么就只能对系统的第一层进行监控,但是如果能够将Zabbix的扩展功能和Zabbix/J灵活地结合使用,那么我们就能够对整个系统进行全方位的、立体的监控!

四、运行和分析示例程序

Zabbix/J的源码目录中包含两个子目录:

  • zabbixj:Zabbix/J探针的核心实现代码,可以编译为jar包,然后添加到自己的工程中。源代码将会在另外一篇文章中进行解析。
  • zabbixj-examples:Zabbix/J使用方法的示例代码。

zabbixj-examples目录中包含四个示例代码文件:

  • ExampleMetricsProvider.java:示范如何编写Zabbix/J可用的自定义监控项。
  • ExamplePassiveAgent.java:示范如何实例化、配置和启动一个Zabbix/J的被动式探针。
  • ExampleActiveAgent.java:示范如何实例化、配置和启动一个Zabbix/J的主动式探针。
  • ExamplePassiveAgentClient.java:示例如何编写一个被动式探针的客户端,模拟如何向Zabbix/J的被动式探针请求查询监控数据。

1. 自定义监控项

在Zabbix/J中,监控数据是由MetricsProvider的实例提供的,本文将这种实例称为监控数据提供者。示例的ExampleMetricsProvider类就是一个监控数据提供者,代码如下图所示:

自定义监控项示例

由上图中的代码可知,ExampleMetricsProvider类实现了MetricsProvider接口,也就是实现了接口的getValue方法。这个方法有一个类型为MetricsKey的参数,这个参数就是监控项的关键字。在Zabbix的前端页面中配置监控项时,必须填写这个监控项关键字,否则Zabbix服务器就不能获取相关的监控数据。监控项关键字将会在第五章中进行详细描述。

这个自定义的监控项将会返回一个随机浮点数作为监控数据。如果传入的监控项关键字不带有参数,那么这个随机数最大不会超过100;如果传入的监控项关键字带有参数,那么这个随机数最大不会超过参数指定的数值。

2. 被动式探针

2.1 代码分析

ExamplePassiveAgent类只有一个main方法,会实例化、配置和启动一个被动式探针,代码如下图所示:

被动式探针示例

由上图中的代码可知,运行程序之前,需要为main方法提供一个参数,这个参数就是被动式探针需要监听的本机端口号。main方法会首先实例化被动式探针,然后将这个探针的监听端口号配置为参数指定的端口号,然后添加两个分别名为examplejava的监控数据提供者,最后启动被动式探针的线程。

2.2 运行示例代码

Step-1 在Spring Tools Suite中启动ExamplePassiveAgent,指定参数为20050(注意,不能和Zabbix原生探针监听的端口号相同,原生探针默认监听10050端口),如下图所示:

运行ExamplePassiveAgent

Step-2 在Zabbix的前端页面中注册Zabbix/J探针所在的主机,各项配置参数如下图所示:

注册ZabbixJ主机

若注册成功,那么主机列表中的状态应该如下图所示:

ZabbixJ主机状态

Step-3 在Zabbix的前端页面上,为上面注册的ZabbixJ-Agent主机新建一个监控项,参数配置如下图所示:

随机数监控项配置示例

Step-4 进入Zabbix前端页面的最新数据页面,稍等片刻就能看到被动式探针返回的监控数据了,如下图所示:

随机数监控项的最新监控数据

点击上图中的“Graph”超链接,还能够看到监控数据的历史图表,如下图所示:

随机数监控项的历史数据图

3. 主动式探针

3.1 代码分析

ExampleActiveAgent类只有一个main方法,会实例化、配置和启动一个主动式探针,代码如下图所示:

主动式探针示例

由上图中的代码可知,运行程序之前,需要为main方法提供三个参数:hostName(Zabbix/J探针主机名)、serverAddress(Zabbix服务器的IP地址)、serverPort(Zabbix服务器的监听端口号)。注意,探针主机名必须要和Zabbix前端页面中注册的主机名完全相同,在本文的示例中就是“ZabbixJ-Agent”。

main方法会首先实例化一个主动式探针,然后显式地启用主动模式和禁用被动模式(探针默认工作在被动模式下),然后配置探针的主机名、Zabbix服务器的IP地址、Zabbix服务器的监听端口号,然后添加两个分别名为examplejava的监控数据提供者,最后启动主动式探针的线程。

3.2 运行示例代码

Step-1 在Spring Tools Suite中启动ExampleActiveAgent,指定参数为“ZabbixJ-Agent 10.24.17.207 10051”,如下图所示:

运行ExampleActiveAgent

Step-2 在Zabbix的前端页面上,为前面已经注册的ZabbixJ-Agent主机新建一个监控项,参数配置如下图所示:

JVM空闲内存监控项配置示例

Step-3 进入Zabbix前端页面的最新数据页面,稍等片刻就能看到主动式探针发送的监控数据了,如下图所示:

JVM空闲内存的最新监控数据

点击上图中的“Graph”超链接,还能够看到监控数据的历史图表,如下图所示:

JVM空闲内存监控项数据图表

4. 被动式探针的客户端

4.1 代码分析

ExamplePassiveAgentClient类实现了一个被动式探针的客户端,启动之后便会定时向先前启动的被动式探针请求查询监控数据了,代码如下图所示:

被动式探针的客户端示例

由上图中的代码可知,运行程序之前,需要为main方法提供四个参数:address(探针主机的IP地址)、port(探针监听的端口号)、-d<sec>(轮询间隔时间)、<key> … <keyN>(监控项列表)。其中,address既可以是Zabbix/J探针的IP地址,也可以是Zabbix原生探针的IP地址;port既可以是Zabbix/J探针的监听端口号(20050),也可以是Zabbix原生探针的监听端口号(10050);-d<sec>的单位为秒,是非必填参数;<key> ... <keyN>列表中的监控项必须是addressport所指定的探针能够支持的监控项,否则采集到的监控数据将会是“Unknown Key”或“Not Supported”之类的错误消息,这也就意味着,这个客户端也可以获取Zabbix原生监控项的监控数据(例如,system.cpu.load[percpu,avg1])。

main方法会首先实例化客户端,然后每隔一段时间就会将监控项列表传给被动式探针,请求查询相应的监控数据,最后将获取的监控数据输出至控制台上,周而复始地无限循环。displayValues方法会将获取的最新监控数据,以及上次和最新监控数据的差值输出至控制台上。

4.2 运行示例代码

Step-1 在Spring Tools Suite中启动ExamplePassiveAgentClient,指定参数为“10.24.16.133 20050 -d10 java.memory.max java.memory.total java.os.name java.os.arch”,如下图所示:

运行ExamplePassiveAgentClient

Step-2 可以在Spring Tools Suite的控制台中看到这个客户端获取的监控数据,随着时间的推移,控制台中的监控数据会不断滚动,如下图所示:

Spring Tools Suite的控制台输出

Step-3 停止运行ExamplePassiveAgentClient示例程序。然后在Spring Tools Suite中再次启动ExamplePassiveAgentClient,指定参数为“10.24.16.133 10050 -d30 system.cpu.load[percpu,avg1]”,如下图所示:

获取Zabbix原生探针的监控数据

此次运行时指定的监控项是Zabbix自带的原生监控项,可用于监控1分钟之内的CPU平均负载。

Step-4 可以在Spring Tools Suite的控制台中看到这个客户端获取的CPU平均负载监控数据,随着时间的推移,控制台中的监控数据会不断滚动,如下图所示:

Zabbix原生监控项的监控数据

五、总结

综上所述,我们可以看到:

  • Zabbix和Zabbix/J的结合使用能够全方位、无死角地监控整个系统;
  • Zabbix和Zabbix/J之间具有完美的兼容性和互操作性。

除此之外,Zabbix/J还提供了一种思路:既然可以使用Java来实现一种Zabbix探针,那么使用其他语言也可以办到同样的事情,若对源码和通信协议进行分析,我们还可以开发出Zabbix/C、Zabbix/PHP、Zabbix/Python等适用于其他语言的监控探针!