当前位置: 首页 > news >正文

通过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观察监控情况。

wKiom1ne50uhAaIkAABQ3-C3sJ8940.png-wh_50

3.1


就此配置工作完成。

 4.结语

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


相关文章:

  • Wpf 之Canvas介绍
  • 杯具的vmware和virtual box虚拟机转换
  • 【转】keyCode对照表及JS监听组合按键
  • 第41周日思考如何更好的工作
  • WordPress 介绍
  • Python-装饰器详解
  • hexo 常用命令
  • Android各层推荐开发书籍及参考资料
  • [Asp.net mvc]国际化
  • springIOC学习笔记
  • 云服务器Windows 2012 IIS添加站点绑定域名的方法?
  • 用香蕉也能玩电脑游戏—Tensorflow对象检测接口的简单应用
  • 《学习opencv》笔记——矩阵和图像操作——cvSetIdentity,cvSolve,cvSplit,cvSub,cvSubS and cvSubRS...
  • JSF导航规则
  • WebBrowser 安全
  • 8年软件测试工程师感悟——写给还在迷茫中的朋友
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • EOS是什么
  • express如何解决request entity too large问题
  • flutter的key在widget list的作用以及必要性
  • Javascript Math对象和Date对象常用方法详解
  • Js基础知识(一) - 变量
  • MD5加密原理解析及OC版原理实现
  • Python_OOP
  • react 代码优化(一) ——事件处理
  • Spring Cloud Feign的两种使用姿势
  • Vue--数据传输
  • Web标准制定过程
  • 从setTimeout-setInterval看JS线程
  • 精彩代码 vue.js
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 判断客户端类型,Android,iOS,PC
  • 软件开发学习的5大技巧,你知道吗?
  • 山寨一个 Promise
  • 使用docker-compose进行多节点部署
  • 正则学习笔记
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • 做一名精致的JavaScripter 01:JavaScript简介
  • ​VRRP 虚拟路由冗余协议(华为)
  • ​虚拟化系列介绍(十)
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (vue)页面文件上传获取:action地址
  • (zt)最盛行的警世狂言(爆笑)
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (翻译)terry crowley: 写给程序员
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (附源码)ssm码农论坛 毕业设计 231126
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (转)Sublime Text3配置Lua运行环境
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)