通過Nagios監控Tomcat服務
通過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<ObjectName> 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[i].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[i].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觀察監控情況。
圖3.1 |
就此配置工作完成。
4.結語
本文介紹了一種通過Nagios監控Tomcat應用的實現方式,按照Nagios Plugin API規則編寫自己的Shell腳本實現該功能,並簡單的描述了配置過程,提供了Shell源碼。希望大家指正。
本文出自 “sky” 博客,請務必保留此出處http://skymax.blog.51cto.com/365901/1971655
通過Nagios監控Tomcat服務