zabbix使用zabbix_java_gateway 监控java应用进程

简介:

JAVA-GATEWAY

Zabbix本身不支持直接监控Java,在zabbix 1.8以前,只能使用Zapcat来做代理监控,

而且要修改源代码,非常麻烦。所有后来为了解决这个监控问题,

Zabbix和Java双方应运生成了各自的代理监控程序:zabbix 2.0以后添加了服务进程

zabbix-java-gateway;Java有了JMX,全称是Java Management Extensions,即Java管理扩展

wKioL1hA8FKiTpeWAABu7oWbNfE824.png

比如:当Zabbix-Server需要知道java应用程序的某项性能的时候,

会启动自身的一个Zabbix-JavaPollers进程去连接Zabbix-JavaGateway请求数据,

而ZabbixJavagateway收到请求后使用“JMXmanagementAPI”去查询特定的应用程序,

而前提是应用程序这端在开启时需要“-Dcom.sun.management.jmxremote”参数来

开启JMX远程查询就行。

Java程序会启动自身的一个简单的小程序端口12345向Zabbix-JavaGateway提供请求数据。


开始监控部署  

从上面的原理图中我们可以看出,配置Zabbix监控Java应用程序的关键点在于:

配置Zabbix-JavaGateway、让Zabbix-Server能够连接Zabbix-JavaGateway、

Tomcat开启JVM远程监控功能等





网上的大多数文章都配置的是被动模式(即zabbix server 去想java进程去取数据),

这样会造成zabbix server的压力过大,所以应该采用主动模式(写一个zabbix类,然后主动去上报数据)


代码如下:

zabbix.py

            1            

="font-family:sans-serif;">="font-size:16px;">cat zabbix.py
-filtered="filtered">#!/usr/bin/python
import os
import time
import socket
import struct
import cPickle
import logging
try:
   from hashlib import sha1
except ImportError:
   from sha import sha as sha1
try:
   import json
except ImportError:
   import simplejson as json
DUMP = 'dump'
if not os.path.isdir(DUMP):
   os.makedirs(DUMP, mode=0755)
class Zabbix(object):
   logger = logging.getLogger('zabbix')
   def __init__(self, values=None):
       if values is not None:
           self.__dict__['values'] = values
   def __getattr__(self, name):
       if name in ('values'):
           return self.__dict__[name]
       return None
   def __setattr__(self, name, value):
       if name == 'values':
           self.__dict__[name] = value
   def gen_request(self, jsons):
       if isinstance(jsons, basestring):
           data = '%s\n' % jsons
       else:
           data = json.dumps(jsons)
       header = 'ZBXD\x01'
       datalen = struct.pack('Q', len(data))
       return header + datalen + data
   def dump(self, host, port, jsons):
       data = {'host': host, 'port': port, 'jsons': jsons}
       hash = sha1(json.dumps(data)).hexdigest()
       path = '%s.%s.%d.%s.error' % (host, port, int(time.time()), hash)
       try:
           write = open(os.path.join(DUMP, path), 'wb')
           cPickle.dump(data, write, -1)
           write.close()
       except:
           self.logger.exception('cannot dump to file %s', path)
   def get_zbx_result(self, host, port, jsons):
       retry = 3
       while retry:
           try:
               data = self._get_zbx_result(host, port, jsons)
               if data is None:
                   break
               return data
           except socket.error:
               self.logger.exception('cannot communit with zabbix')
           time.sleep(5)
           retry -= 1
       self.logger.error('cannot send data to zabbix server')
       self.dump(host, port, jsons)
   def _get_zbx_result(self, host, port, jsons):
       sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
       print host,port,jsons
       sock.connect((host, port))
       sock.send(self.gen_request(jsons))
       print "send %s" % self.gen_request(jsons)
       self.logger.debug('sent %s', jsons)
       recv = sock.recv(5)
       if recv != 'ZBXD\x01':
           self.logger.error('Invalid Response')
           self.dump(host, port, jsons)
           return None
       recv = sock.recv(8)
       (datalen,) = struct.unpack('Q', recv)
       data = sock.recv(datalen)
       sock.close()
       self.logger.debug('received %s', data)
       return data
   def getvalue(self):
       # shoulde be {host: {key: value}}
       return self.values
   def run(self):
       hostvalues = self.getvalue()
       if not isinstance(hostvalues, dict):
           self.logger.error('invalid hostvalues: %s', str(hostvalues))
           return False
       clock = int(time.time())
       jsons = {
           'request': 'agent data',
           'data': [],
           'clock': clock,
       }
       data = jsons['data']
       for host, values in hostvalues.iteritems():
           for key, value in values.iteritems():
               data.append({
                   'host': host,
                   'key': key,
                   'value': value,
                   'clock': clock,
               })
       return self.get_zbx_result(ZBX_HOST, ZBX_PORT, jsons)
   def getjmx(self, host, port, keys):
       jsons = {
           'request': 'java gateway jmx',
           'conn': host,
           'port': port,
           'keys': keys,
       }
       return self.get_zbx_result(JMX_HOST, JMX_PORT, jsons)
ZBX_HOST = 'zabbix.server.com'
ZBX_PORT = 10051
JMX_HOST = 'localhost'
JMX_PORT = 10052
handler = logging.FileHandler(filename='/tmp/zabbix.%s.log' % time.strftime('%Y%m%d'), mode='a')
formatter = logging.Formatter('%(asctime)s %(name)s %(lineno)s %(levelname)s %(message)s')
handler.setFormatter(formatter)
logger = logging.getLogger()
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
if __name__ == '__main__':
   zbx = Zabbix()
   print zbx.getjmx('localhost', 8081, ['jmx["Standalone:type=Manager,path=/,host=localhost",activeSessions]', 'jmx["java.lang:type=Runtime",Uptime]', 'jmx["Catalina:type=GlobalRequestProcessor,name=\\"http-bio-8080\\"",bytesSent]'])
   pass
           

           




cat zabbix_wiki_node1_java.py  

            1            

            2            

            3            

            4            

            5            

            6            

            7            

            8            

            9            

            10            

            11            

            12            

            13            

            14            

            15            

            16            

            17            

            18            

            19            

            20            

            21            

            22            

            23            

            24            

            25            

            26            

            27            

            28            

            29            

            30            

            31            

            32            

            33            

            34            

            35            

            36            

            37            

            38            

            39            

            40            

            41            

            42            

            43            

            44            

            45            

            46            

            47            

            48            

            49            

            50            

            51            

            52            

            53            

            54            

            55            

            56            

            57            

            58            

            59            

            60            

            61            

            62            

            63            

            64            

            65            

            66            

            67            

            68            

            69            

            70            

            71            

            72            

            73            

#!/usr/bin/env python

#fileencoding: utf-8

ITEMS = [

'jmx["java.lang:type=ClassLoading",LoadedClassCount]',

'jmx["java.lang:type=ClassLoading",TotalLoadedClassCount]',

'jmx["java.lang:type=ClassLoading",UnloadedClassCount]',

'jmx["java.lang:type=Memory",HeapMemoryUsage.committed]',

'jmx["java.lang:type=Memory",HeapMemoryUsage.max]',

'jmx["java.lang:type=Memory",HeapMemoryUsage.used]',

'jmx["java.lang:type=Memory",NonHeapMemoryUsage.committed]',

'jmx["java.lang:type=Memory",NonHeapMemoryUsage.max]',

'jmx["java.lang:type=Memory",NonHeapMemoryUsage.used]',

'jmx["java.lang:type=MemoryPool,name=Code Cache",Usage.committed]',

'jmx["java.lang:type=MemoryPool,name=Code Cache",Usage.max]',

'jmx["java.lang:type=MemoryPool,name=Code Cache",Usage.used]',

'jmx["java.lang:type=MemoryPool,name=PS Eden Space",Usage.committed]',

'jmx["java.lang:type=MemoryPool,name=PS Eden Space",Usage.max]',

'jmx["java.lang:type=MemoryPool,name=PS Eden Space",Usage.used]',

'jmx["java.lang:type=MemoryPool,name=PS Old Gen",Usage.committed]',

'jmx["java.lang:type=MemoryPool,name=PS Old Gen",Usage.max]',

'jmx["java.lang:type=MemoryPool,name=PS Old Gen",Usage.used]',

'jmx["java.lang:type=MemoryPool,name=PS Perm Gen",Usage.committed]',

'jmx["java.lang:type=MemoryPool,name=PS Perm Gen",Usage.max]',

'jmx["java.lang:type=MemoryPool,name=PS Perm Gen",Usage.used]',

'jmx["java.lang:type=MemoryPool,name=PS Survivor Space",Usage.committed]',

'jmx["java.lang:type=MemoryPool,name=PS Survivor Space",Usage.max]',

'jmx["java.lang:type=MemoryPool,name=PS Survivor Space",Usage.used]',

'jmx["java.lang:type=OperatingSystem",MaxFileDescriptorCount]',

'jmx["java.lang:type=OperatingSystem",OpenFileDescriptorCount]',

'jmx["java.lang:type=Runtime",Uptime]',

'jmx["java.lang:type=Threading",DaemonThreadCount]',

'jmx["java.lang:type=Threading",PeakThreadCount]',

'jmx["java.lang:type=Threading",ThreadCount]',

'jmx["java.lang:type=Threading",TotalStartedThreadCount]',

'jmx["Standalone:type=GlobalRequestProcessor,name=http-8090",bytesReceived]',

'jmx["Standalone:type=GlobalRequestProcessor,name=http-8090",bytesSent]',

'jmx["Standalone:type=GlobalRequestProcessor,name=http-8090",errorCount]',

'jmx["Standalone:type=GlobalRequestProcessor,name=http-8090",processingTime]',

'jmx["Standalone:type=GlobalRequestProcessor,name=http-8090",requestCount]',

'jmx["Standalone:type=Manager,path=/,host=localhost",activeSessions]',

'jmx["Standalone:type=Manager,path=/,host=localhost",maxActiveSessions]',

'jmx["Standalone:type=Manager,path=/,host=localhost",maxActive]',

'jmx["Standalone:type=Manager,path=/,host=localhost",rejectedSessions]',

'jmx["Standalone:type=Manager,path=/,host=localhost",sessionCounter]',

'jmx["Standalone:type=ProtocolHandler,port=8090",compression]',

'jmx["Standalone:type=ThreadPool,name=http-8090",currentThreadCount]',

'jmx["Standalone:type=ThreadPool,name=http-8090",currentThreadsBusy]',

'jmx["Standalone:type=ThreadPool,name=http-8090",maxThreads]',

]

from zabbix import Zabbix

from zabbix import json

def getjmxkey(key):

   # key = key.replace('http-8080', '\\"http-bio-8080\\"')

   # key = key.replace('path=/', 'context=/')

   return key

def getjmxvalue(value):

   if isinstance(value, dict):

       return value.get('value', u'').encode('utf8')

   return ''

if __name__ == '__main__':

   host = 'it-tw01'

   zbx = Zabbix()

   jmxkeys = [getjmxkey(x) for x in ITEMS]

   data = zbx.getjmx('it-tw01', '8410', jmxkeys)

   try:

       results = json.loads(data)

   except:

       results = {}

   if isinstance(results, dict) and results['response'] == 'success':

       jmxvalues = [getjmxvalue(x) for x in results.get('data', [])]

       hostvalues = {host: dict(zip(ITEMS, jmxvalues))}

       Zabbix(hostvalues).run()

# vim: set sta sw=4 et:


crontab

* * * * * /home/sankuai/monitor/zabbix_wiki_node1_java.py


zabbix

/etc/zabbix# ls

zabbix_agentd.conf  zabbix_agentd.confn-place  zabbix_agentd.d  zabbix_java_gateway.conf


it-tw01需要关联的模板见附件




特别注意:

编译安装zabbix server需要加上--enable-java以支持jmx监控,如果之前的zabbix server没加,那么请重新编译安装,参考编译参数

安装软件

yum install -y java java-devel zabbix-java-gateway



附件:http://down.51cto.com/data/2368443


     本文转自Tenderrain 51CTO博客,原文链接:http://blog.51cto.com/tenderrain/1878822,如需转载请自行联系原作者







相关文章
|
1月前
|
人工智能 Java API
Java也能快速搭建AI应用?一文带你玩转Spring AI可落地性
Java语言凭借其成熟的生态与解决方案,特别是通过 Spring AI 框架,正迅速成为 AI 应用开发的新选择。本文将探讨如何利用 Spring AI Alibaba 构建在线聊天 AI 应用,并实现对其性能的全面可观测性。
|
25天前
|
人工智能 Java API
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
|
1月前
|
存储 缓存 监控
|
27天前
|
缓存 Java 物联网
CRaC技术助力ACS上的Java应用启动加速
容器计算服务借助ACS的柔性算力特性并搭配CRaC技术极致地提升Java类应用的启动速度。
|
27天前
|
人工智能 Java API
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
|
2月前
|
监控 Java 应用服务中间件
tomcat相关概念与部署tomcat多实例-zabbix监控(docker部署)
通过上述步骤,您可以在Ubuntu系统上成功编译并安装OpenCV 4.8。这种方法不仅使您能够定制OpenCV的功能,还可以优化性能以满足特定需求。确保按照每一步进行操作,以避免常见的编译问题。
68 23
|
2月前
|
Java 编译器 开发者
Java中的this关键字详解:深入理解与应用
本文深入解析了Java中`this`关键字的多种用法
253 9
|
2月前
|
Java 应用服务中间件 API
【潜意识Java】javaee中的SpringBoot在Java 开发中的应用与详细分析
本文介绍了 Spring Boot 的核心概念和使用场景,并通过一个实战项目演示了如何构建一个简单的 RESTful API。
60 5
|
2月前
|
人工智能 自然语言处理 搜索推荐
【潜意识Java】了解并详细分析Java与AIGC的结合应用和使用方式
本文介绍了如何将Java与AIGC(人工智能生成内容)技术结合,实现智能文本生成。
269 5
|
2月前
|
SQL Java 数据库连接
【潜意识Java】深入理解MyBatis,从基础到高级的深度细节应用
本文详细介绍了MyBatis,一个轻量级的Java持久化框架。内容涵盖MyBatis的基本概念、配置与环境搭建、基础操作(如创建实体类、Mapper接口及映射文件)以及CRUD操作的实现。此外,还深入探讨了高级特性,包括动态SQL和缓存机制。通过代码示例,帮助开发者更好地掌握MyBatis的使用技巧,提升数据库操作效率。总结部分强调了MyBatis的优势及其在实际开发中的应用价值。
46 1

热门文章

最新文章

推荐镜像

更多