|
通过Nagios监控Tomcat服务
1.前言
本文主要介绍如何通过Nagios软件来监控Tomcat服务运行状况,其中主要包括Tomcat Server以及JDBC Pool的运行状态。Nagios的插件中本身并不提供对于Tomcat服务监控的功能,所以要根据Nagios PluginAPI编写自己的脚本,扩展其插件,完成我们所需要的功能。对于Tomcat运行状态信息的获得需通过JMX。
本文参考了Nagios3的官方文档中有关Nagios Plugin部分,以及Tomcat官方文档有关JMX和命令行部分,具体的Tomcat版本是7.0.81(JDK7)。
2.NagiosPlugin API概述
作为一个Nagios插件,无论你是用脚本(如shell、perl)还是用c编译后的可执行程序实现,它必须至少完成两件事,
1、退出时有一个返回值。
2、至少向标准输出设备(STDOUT)输出一行文本。
返回值定义:
Plugin Return Code
| Service State
| Host State
| 0
| OK
| UP
| 1
| WARNING
| UP or DOWN/UNREACHABLE*
| 2
| CRITICAL
| DOWN/UNREACHABLE
| 3
| UNKNOWN
| DOWN/UNREACHABLE
| 输出文本至少要一行,其信息主要反映被监控应用、服务的状态。
例如:DISK OK - free space: / 3326 MB (56%);
3.监控Tomcat的实现方法
对于Tomcat运行状况的获得,我们是通过JMX访问Tomcat的方式实现的,通过JVM的queryMBeans方法查询获取具体的Mbean(Thread、JVM、JDBC),根据bean的属性值判断运行状态。
3.1. Tomcat开启RMI
若通过JMX连接Tomcat,需开启Tomcat的RMI。开启需要指定具体端口,具体配置如下,需将如下代码加入Tomcat启动脚本。
export JMX_REMOTE_CONFIG="
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8999
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password
-Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access
"
export CATALINA_OPTS="$CATALINA_OPTS $JMX_REMOTE_CONFIG"
| 重启tomcat,并检查参数是否生效(通过ps –ef|grep java 查看参数是否已加入,通过netstat –lanp 查看端口是否启动)。
我们在这里选择了需要认证,并配置了访问控制文件。
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password
-Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access
| 登录用户monitorRole,权限readonly(只读)
cat ../conf/jmxremote.access
monitorRole readonly
| 登录用户monitorRole以及密码
cat ../conf/jmxremote.password
monitorRole tomcat0930
|
3.2. 通过JMX访问Tomcat
通过JMXConnectorFactory类,经JMX协议连接Tomcat的jmxrmi,注意这里需要进行认证。
String jmxURL = "service:jmx:rmi:///jndi/rmi://localhost:8999/jmxrmi";
JMXServiceURL serviceURL;
serviceURL = new JMXServiceURL(jmxURL);
Map map = new HashMap();
String[] credentials = new String[] { "monitorRole", "XXXXX" };
map.put("jmx.remote.credentials", credentials);
JMXConnector connector = JMXConnectorFactory.connect(serviceURL,
map);
MBeanServerConnection mbsc = connector.getMBeanServerConnection();
|
3.3. Tomcat运行状态信息获得
通过MBeanServerConnection获得具体的MBean。并通过MBean的属性获得运行状态。Thread、JVM、JDBC对应的属性获取方式具体如下。
Thread
ObjectName ObjName = new ObjectName(
"Catalina:name=\"http-bio-*\",type=ThreadPool");
Set mbeanManagerSet = mbsc.queryNames(ObjName, null);
// System.out.println("MBeanset1.size:" + MBeanset1.size());
System.out.println("#THREAD#");
for (ObjectName obj : mbeanManagerSet) {
ObjectName objectName = new ObjectName(obj.getCanonicalName());
String canonicalName = objectName.getCanonicalName();
// System.out.println("objectInstance : " + objectInstance);
System.out.println("+canonicalName : " + canonicalName);
MBeanInfo info = mbsc.getMBeanInfo(objectName);
MBeanAttributeInfo[] ainfo = info.getAttributes();
// 逐一获得属性值
for (int i = 0; i < ainfo.length; i++) {
String attributeName = ainfo.getName();
String attributeinfo = getAttributeByNmae(mbsc, objectName,
attributeName);
if (!("".equals(attributeinfo) || attributeinfo.isEmpty())) {
System.out.println(attributeinfo);
}
}
System.out.println("-canonicalName : " + canonicalName);
}
}
|
JVM
ObjectName heapObjName = new ObjectName("java.lang:type=Memory");
MemoryUsage heapMemoryUsage;
System.out.println("#JVM#");
System.out.println("+HeapMemoryUsage");
try {
heapMemoryUsage = MemoryUsage.from((CompositeDataSupport) mbsc
.getAttribute(heapObjName, "HeapMemoryUsage"));
long maxMemory = heapMemoryUsage.getMax();// 堆最大
long commitMemory = heapMemoryUsage.getCommitted();// 堆当前分配
long usedMemory = heapMemoryUsage.getUsed();
System.out.println(" Max:" + maxMemory);
System.out.println(" Committed:" + commitMemory);// 堆当前分配
System.out.println(" HeapPercent:"
+ (int) (usedMemory * 10000 / commitMemory) + "");// 堆使用率
} catch (AttributeNotFoundException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
} catch (MBeanException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
}
System.out.println("-HeapMemoryUsage");
|
JDBC
// 获得javax.sql.DataSource信息
ObjectName ObjName = new ObjectName(
"Catalina:class=javax.sql.DataSource,context=/*,host=localhost,name=\"*\",type=DataSource");
Set mbeanJDBCSet = mbsc.queryMBeans(ObjName, null);
// System.out.println("MBeanset1.size:" + MBeanset1.size());
Iterator MBeansetIterator1 = mbeanJDBCSet.iterator();
System.out.println("#JDBC#");
while (MBeansetIterator1.hasNext()) {
ObjectInstance objectInstance = (ObjectInstance) MBeansetIterator1
.next();
ObjectName objectName = objectInstance.getObjectName();
String canonicalName = objectName.getCanonicalName();
// System.out.println("objectInstance : " + objectInstance);
System.out.println("+canonicalName : " + canonicalName);
MBeanInfo info = mbsc.getMBeanInfo(objectName);
MBeanAttributeInfo[] ainfo = info.getAttributes();
// 逐一获得属性值
for (int i = 0; i < ainfo.length; i++) {
String attributeName = ainfo.getName();
String attributeinfo = getAttributeByNmae(mbsc, objectName,
attributeName);
if (!("".equals(attributeinfo) || attributeinfo.isEmpty())) {
System.out.println(attributeinfo);
}
}
System.out.println("-canonicalName : " + canonicalName);
}
|
3.4. Nrpe Nagios Plugin
check_tomcat脚本逻辑如下(伪代码),
case "$v_cmd" in
--JVM)
获取JVM信息
如果获取出错,返回STATE_UNKNOWN状态
如果HeapPercent大于crit,返回STATE_CRITICAL状态
如果HeapPercent大于crit,返回STATE_WARNING状态
返回STATE_OK状态
--JDBC)
获取JDBC信息
v_state_crit=0
v_state_warn=0
逐一处理JDBC
如果maxActive小于等于numActive(活动数已经等于最大值),v_state_crit=1
如果numActive大于0并且v_numIdle小于等于0(有活动且空闲数为零),v_state_warn=1
如果v_state_crit=1,返回STATE_CRITICAL状态
如果v_state_warn=1,返回STATE_WARNING状态
返回STATE_OK状态
--THREAD)
获取Thread信息
v_state_crit=0
v_state_warn=0
逐一处理Thread
如果maxConnections小于等于currentThreadCount(线程数已经等于最大值),v_state_crit=1
如果currentThreadCount小于等于connectionCount(活动数已经达到线程数),v_state_warn=1
如果v_state_crit=1,返回STATE_CRITICAL状态
如果v_state_warn=1,返回STATE_WARNING状态
返回STATE_OK状态
|
3.5. Nagios监控配置
Nrpe端
./libexec下部署check_tomcat.sh脚本,并部署TomcatJMX.class到./libexec/tomcat/com/tomcat/jmx下。
./etc/nrpe.cfg
command[check_tomcat_JDBC]=/usr/local/nagios/libexec/check_tomcat.sh --JDBC
command[check_tomcat_JVM]=/usr/local/nagios/libexec/check_tomcat.sh --JVM 9998 9999
command[check_tomcat_THREAD]=/usr/local/nagios/libexec/check_tomcat.sh --THREAD
|
Server端
./etc/nagios.cfg
define service{
use tomcat-service
host_name linux_XX
service_description check-wls-console--JDBC
check_command check_nrpe!check_tomcat_JDBC
}
define service{
use tomcat-service
host_name linux_XX
service_description check-wls-console--JVM
check_command check_nrpe!check_tomcat_JVM
}
define service{
use tomcat-service
host_name linux_XX
service_description check-wls-console--THREAD
check_command check_nrpe!check_tomcat_THREAD
}
| 验证配置是否正确。
重启监控主机上的nagios服务以及远程主机上的nrpe服务。
通过IE观察监控情况。
就此配置工作完成。
4.结语
本文介绍了一种通过Nagios监控Tomcat应用的实现方式,按照Nagios Plugin API规则编写自己的Shell脚本实现该功能,并简单的描述了配置过程,提供了Shell源码。希望大家指正。
附件:http://down.运维网.com/data/2367039
|
|
|