通过Nagios监控Tomcat服务
英语文化交流 > 技术博客 > 通过Nagios监控Tomcat服务
通过Nagios监控Tomcat服务
时间:2017-10-12 11:51:56 sky 分类:技术博客

 

通 过 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 Cef|grep java 查 看 参 数 是 否 已 加 入 ,通 过 netstat Clanp 查 看 端 口 是 否 启 动 )。

我 们 在 这 里 选 择 了 须 要 认 证 ,并 配 置 了 访 问 控 制 文 件 。

-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观 察 监 控 状 况 。

wKiom1ne50uhAaIkAABQ3-C3sJ8940.png-wh_50

3.1


就 此 配 置 工 作 完 成 。

 4.结 语

本 文 介 绍 了 一 种 通 过 Nagios监 控 Tomcat应 用 的 实 现 方 式 ,按 照 Nagios Plugin API规 则 编 写 自 己 的 Shell脚 本 实 现 该 功 能 ,并 简 单 的 描 述 了 配 置 过 程 ,提 供 了 Shell源 码 。希 望 大 家 指 正 。


本 文 出 自 “sky” 博 客 ,请 务 必 保 留 此 出 处 http://****/365901/1971655

随机阅读

Copyright © 2017 英语文化交流 All Rights Reserved.