Zabbix/J是一个Java版本的系统监控框架,它可以完美地兼容于Zabbix监控系统,使得开发、运维等技术人员能够对整个业务系统的基础设施、应用软件/中间件和业务逻辑进行全方位的分层监控。
Spring是一种分层的Full-Stack(全栈)的轻量级开源框架,适用于JavaSE和JavaEE。Spring使用基本的JavaBean代替笨重的EJB,这样便降低了企业应用开发的复杂性。
本文将搭建一个最小化的SpringMVC工程,然后会将Zabbix/J整合入这个工程之中,最后在Zabbix的前端页面上监控这个最小化Web系统的三层监控数据。
在阅读本文之前,你最好对Zabbix和Spring有一定的使用经验,有兴趣的话还可以阅读以下扩展文章,有利于加深理解整个流程:
若要了解Zabbix的工作模式,请参考《Zabbix探针工作模式解析》。
若要了解Zabbix/J监控框架,请参考《一种Java实现的Zabbix监控框架——Zabbix/J》。
若要了解Zabbix/J的工作原理,请参考《Zabbix/J的源代码解析》。
一、环境描述
1. Zabbix Server
操作系统:CentOS 6.6 x86_64
IP地址:10.24.17.207
版本:2.4.8
安装方法:参考《在CentOS上通过编译源码安装Zabbix服务端》安装
2. Zabbix Agent
操作系统:Windows 7 SP1 64位
IP地址:10.24.16.175
版本:2.4.4
安装方法:参考《在Windows上安装Zabbix Agent》安装
3. Zabbix/J
操作系统:同Zabbix Agent
IP地址:同Zabbix Agent
版本:1.0.1
安装方式:Maven
4. Java环境
操作系统:同Zabbix Agent
IP地址:同Zabbix Agent
JDK版本:1.7.0_60
IDE版本:Spring Tool Suite 3.6.3.RELEASE
Spring版本:4.2.4.RELEASE
Tomcat版本:apache-tomcat-8.0.24
5. Redis缓存
操作系统:CentOS 6.6 x86_64 Minimal
IP地址:10.24.16.87
版本:3.2.1
安装方法:参考《在CentOS上安装Redis缓存系统》安装(注意,由于头条号的内链总数不能超过5个,所以读者需要手动访问这篇文章的链接:
http://toutiao.com/i6312315323185889794/)
二、搭建最小化的SpringMVC工程
本文会将Zabbix/J整合入一个名为SpringTest的最小化工程,这个工程请参考《如何搭建SpringMVC的最小化工程》进行搭建(注意,由于头条号的内链总数不能超过5个,所以读者需要手动访问这篇文章的链接:
http://toutiao.com/i6311898228245660161/)。注意,由于操作系统和使用JDK版本不同,请读者自行裁剪和修改参考文章中的详细步骤(例如,将POM文件中的编译器版本修改为1.7,等等)。
三、整合Zabbix/J和Spring
整合Zabbix/J和Spring包含多个步骤,需要对前述的SpringMVC最小化工程进行改造,包括引入依赖包、注入探针实例、修改代码,等等。
1. 引入依赖包
在/SpringTest/pom.xml
文件中引入Jedis和Zabbix/J的JAR包:
jedis-2.1.0.jar:本文将会使用Redis缓存来存储页面访问次数,因此需要通过这个JAR包访问Redis缓存。
zabbixj-1.0.1.jar:本文将会在WEB容器的启动监听器中通过注入的方式实例化Zabbix/J探针,因此需要通过这个JAR包提供探针配置和数据收集的功能。
这个POM文件的最终内容如下所示:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>SpringTest</groupId>
<artifactId>SpringTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!-- springframework begins -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>com.quigley</groupId>
<artifactId>zabbixj</artifactId>
<version>1.0.1</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. 新建Redis客户端类
新建RedisClient
类,文件路径为:
。这个类提供了手动获取和释放Redis连接的功能,以及设置、获取和删除存储在Redis中的Key-Value对的功能。这个类的代码如下所示:
/SpringTest/src/hello/RedisClient.java
package hello;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class RedisClient {
// Redis客户端连接
private Jedis jedis;
// Redis连接池
private JedisPool jedisPool;
// Redis客户端构造器
public RedisClient(String host, int port) {
initialPool(host, port);
jedis = jedisPool.getResource();
}
// 初始化Redis连接池
private void initialPool(String host, int port) {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxActive(20);
config.setMaxIdle(5);
config.setMaxWait(1000l);
config.setTestOnBorrow(false);
jedisPool = new JedisPool(config, host, port);
}
// 设置String类型的键值对
public String set(String key, String value) {
return jedis.set(key, value);
}
// 获取String类型的键值对
public String get(String key) {
return jedis.get(key);
}
// 删除String类型的键值对
public long del(String key) {
return jedis.del(key);
}
// 检查String类型的键值对是否存在
public boolean exists(String key) {
return jedis.exists(key);
}
// 清空Redis数据库
public String flushDB() {
return jedis.flushDB();
}
// 释放Redis连接
public void free() {
jedisPool.returnResource(jedis);
}
}
3. 新建监控数据提供者类
新建TestMetricsProvider
类,文件路径为:
。这个类的实例是一个监控数据提供者,Zabbix/J探针会通过这个实例获取测试页面的访问次数。这个类的代码如下所示:
/SpringTest/src/hello/TestMetricsProvider.java
package hello;
import com.quigley.zabbixj.metrics.MetricsException;
import com.quigley.zabbixj.metrics.MetricsKey;
import com.quigley.zabbixj.metrics.MetricsProvider;
public class TestMetricsProvider implements MetricsProvider {
public Object getValue(MetricsKey mKey) throws MetricsException {
if (mKey.getKey().equals("page.count")) {
RedisClient rc = new RedisClient("10.24.16.87", 6379);
long counter = new Long(rc.get("counter"));
rc.free();
return counter;
}
throw new MetricsException("Unknown Key: " + mKey.getKey());
}
}
TestMetricsProvider
类继承了Zabbix/J的MetricsProvider
接口,当Zabbix服务端定时向探针发送查询请求时,这个类的实例便会查询和返回相应的监控数据。
4. 新建WEB容器启动监听器类
新建StartupListener
类,文件路径为:
。这个类的实例会在Web容器启动时初始化应用的上下文配置,此处主要负责配置Zabbix/J探针的端口号和监控数据提供者,然后启动探针线程。这个类的代码如下所示:
/SpringTest/src/hello/StartupListener.java
package hello;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import com.quigley.zabbixj.agent.ZabbixAgent;
import com.quigley.zabbixj.providers.JVMMetricsProvider;
public class StartupListener implements ApplicationContextAware {
@Autowired
private ZabbixAgent zabbixAgent;
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
try {
zabbixAgent.setListenPort(20050);
zabbixAgent.addProvider("java", new JVMMetricsProvider());
zabbixAgent.addProvider("test", new TestMetricsProvider());
zabbixAgent.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意,必须在Spring容器中注册这个监听器的实例,否则当Web容器启动时便不能对应用上下文进行初始化配置。
5. 改造测试类
现在,还需要对已有的HelloController
测试类进行改造,现在这个类的代码如下所示:
package hello;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@RequestMapping("hello")
public @ResponseBody String test() {
RedisClient rc = new RedisClient("10.24.16.87", 6379);
if (!rc.exists("counter")) {
rc.set("counter", "0");
}
int counter = Integer.valueOf(rc.get("counter")) + 1;
rc.set("counter", String.valueOf(counter));
rc.free();
return String.format("hello, world! This comes from spring, visited %d times!", counter);
}
}
实际上只是将测试类中的页面访问计数器由全局变量改为存放在Redis中,便于Zabbix/J探针定时获取数据。
6. 注册Bean
修改已有的applicationContext.xml
配置文件,添加启动监听器和Zabbix/J探针的配置信息。修改后的配置文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:annotation-config />
<bean class="hello.StartupListener" />
<bean id="zabbixAgent" class="com.quigley.zabbixj.agent.ZabbixAgent" />
</beans>
其中,第13行表示使用Spring注解实现注入,第14行是启动监听器的bean注册信息,第15行是Zabbix/J探针的bean注册信息。
7. 测试工程的最终结构
整合后的测试工程的最终结构如下图所示:
四、配置Zabbix监控
1. 启动测试工程
在Eclipse的Servers
视图中,右键点击测试工程对应的Tomcat服务器,在右键菜单中选择执行或
选项,如下图所示:
在浏览器中访问
页面,若页面如下图所示,则表示测试工程启动成功:
http://localhost:8080/SpringTest/hello
2. 注册Zabbix/J主机
在浏览器中登录Zabbix服务器,然后打开Configuration → Hosts
配置页面,如下图所示:
点击上图中的Create host
按钮,打开主机注册配置页面,然后填写主机名、IP地址和端口号等信息,详细配置如下图所示:
Zabbix/J主机注册完成之后,稍等几分钟,便能看到主机列表中的Availability
栏中的Z
图标变为绿色,表示这台主机注册成功,如下图所示:
3. 注册监控项
在主机列表页面中,点击ZabbixJ-Agent主机的Items
超链接,打开监控项列表页面,如下图所示:
点击上图中的Create item
按钮,新建JVM空闲内存监控项和页面访问计数监控项,这两个监控项的详细配置如下所示:
JVM空闲内存监控项
页面访问计数监控项
此时,便能在监控项列表中看到这两个监控项了,如下图所示:
五、功能验证
现在,打开Monitoring → Latest data
页面,然后在Hosts
栏中填写ZabbixJ-Agent,这样便能在这个页面中进行过滤,只监控上述两个监控项的监控数据,如下图所示:
至此,Zabbix/J和Spring的整合工作已经全部完成了。