【问题标题】:Jython jmxmp protocol supportJython jmxmp 协议支持
【发布时间】:2011-07-27 12:36:37
【问题描述】:

我正在为zabbix 开发监控脚本和模板集合。它被称为ZTC,所有脚本都在 python 上。

现在我想添加对一些 java 监控的支持。我还没有找到从 CPython 中做到这一点的方法——只能从 java 或 jython 中找到。由于所有项目都在 python 上,我决定在 jython 上编写一个简单的脚本,该脚本将从我的 cpython 类中调用。

我的代码如下所示:

#!/usr/bin/env jython

#Java Dependencies
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.lang.management.ManagementFactory;

#Python Dependencies
import sys, cmd, socket

def usage():
    print """Usage:
    jmxclient.py -h
    jmxclient.py <connect_url> <jmx_attribute_path> <jmx_property>"""

class JMXClient:
    remote = None

    def connect(self, connect_url):
        if self.remote:
            return True

        #Establish Connection to JMX Server
        url = javax.management.remote.JMXServiceURL(connect_url);
        connector = javax.management.remote.JMXConnectorFactory.connect(url);
        self.remote = connector.getMBeanServerConnection();

    def getAttribute(self, mbean_path, attribute):
        """Query the mbean server for a specific attribute and return the
        result"""
        obn =  javax.management.ObjectName(mbean_path);
        result = self.remote.getAttribute(obn, attribute);

        return result    

if len(sys.argv) <= 1:
    usage()
    sys.exit(2)

if sys.argv[1] in ('-h', '--help'):
    usage()
    sys.exit(2)

if len(sys.argv) <> 4:
    usage()
    sys.exit(2)

(connect_url, mbean_path, attribute) = sys.argv[1:]

j = JMXClient()
j.connect(connect_url)
print j.getAttribute(mbean_path, attribute)   

好的,现在我正在尝试从兵马俑服务器获取一些属性。它使用带有 url 服务的 jmxmp:jmx:jmxmp://0.0.0.0:9520。

所以,我按如下方式运行我的脚本:

$ ./jmxclient.py service:jmx:jmxmp://localhost:9520 java.lang.ClassLoading LoadedClassCount
Traceback (innermost last):
  File "./jmxclient.py", line 87, in ?
  File "./jmxclient.py", line 61, in connect
        at javax.management.remote.JMXConnectorFactory.newJMXConnector(JMXConnectorFactory.java:327)
        at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:247)
        at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:207)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)

java.net.MalformedURLException:java.net.MalformedURLException:不支持的协议:jmxmp

(由于一些剥离的 cmets,行号不相关)

如何添加对这个 jmxmp 协议的支持?

我发现它似乎可以由 jmxremote_optional.jar 启用。如何将此 jar 添加到我的 jython(首选不是系统范围内)?

更新

按照建议,我从jmxremote-1_0_1-ri-bin-b58.zip 参考实现:jython -Djava.endorsed.dirs=. -Dpython.path=.../jmxremote_optional.jar:.../jmxremote.jar:.../jmissl.jar jmxclient.py service:jmx:jmxmp://localhost:9520 java.lang.ClassLoading LoadedClassCount 添加了 jmxremote_optional.jar 和 jmxremote.jar,但仍然遇到相同的错误。我确定 jmxremote_optional.jar 在类路径中,并且代码似乎与参考示例非常相似。

阅读 api 文档后,我尝试了以下更改:

url = javax.management.remote.JMXServiceURL('jmxmp', 'localhost', 9520);
connector = javax.management.remote.jmxmp.JMXMPConnector(url)
connector.connect()
self.remote = connector.getMBeanServerConnection();

这导致我遇到另一个例外:

Traceback (innermost last):
  File "../src/jmxclient.py", line 87, in ?
  File "../src/jmxclient.py", line 61, in connect
        at com.sun.jmx.remote.opt.security.AdminClient.connectionOpen(AdminClient.java:209)
        at com.sun.jmx.remote.generic.ClientSynchroMessageConnectionImpl.connect(ClientSynchroMessageConnectionImpl.java:72)
        at javax.management.remote.generic.GenericConnector.connect(GenericConnector.java:177)
        at javax.management.remote.jmxmp.JMXMPConnector.connect(JMXMPConnector.java:119)
        at javax.management.remote.generic.GenericConnector.connect(GenericConnector.java:124)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
java.io.IOException: java.io.IOException: javax.management.remote.message.HandshakeBeginMessage

Jython 版本是 2.2,我不喜欢使用更高版本,因为这个脚本主要用于 RHEL5 机器上,它们只有 jython 2.2.1。

PS:将问题标记为已回答,因为我决定放弃并使用 jmxterm 或类似工具,只需添加 -Djava.endosed.dirs=/path/to/dir_with_jmxremote_optional/ 似乎都可以与 jmxmp 一起使用。 但我仍然希望看到 jython 解决方案。

【问题讨论】:

    标签: java jython jmx


    【解决方案1】:

    伙计,那篇文章我看了大约 7 次.....

    无论如何,这就是我认为正在发生的事情。 jmxmp 协议未打包在标准 J2SE 运行时中。请参阅此page。引用:

    注意 – 如果您想使用 JMXMP 连接器,请从 http://java.sun.com/products/JavaManagement/download.html 下载 JSR 160 参考实现,并将 jmxremote_optional.jar 文件添加到您的类路径中。您将在 JSR 160 参考实现随附的 JMX 远程 API 教程中找到使用 JMXMP 连接器的示例。

    我对 jython 不是很熟悉,但看起来这个 post 应该会吸引你。

    【讨论】:

    • 非常感谢,我已经阅读了示例,甚至修改并运行了它们,它仍然无法通过 jython 工作:(。我想我会使用纯 java 客户端,而不是 jython 客户端。但是如果有更多建议,我将非常感激。顺便说一句,我的问题到底出了什么问题,我不是母语人士,也不是来自 java 世界,我知道我的问题并不完美,只是问我该如何改进它。跨度>
    • 对不起 rvs,这不是关于它是如何编写的评论,我只是无法弄清楚错误来自哪里。你说[或写]很好。
    • 哦,对不起,我误会了。
    【解决方案2】:

    我也遇到过同样的问题。解决方法是使用不同的方法导入jarjmxremote_optional.jar。这里有描述https://stackoverflow.com/a/11638390/9209536

    此代码适用于 Jython 2.7

    def importJar(jarFile):
        from java.net import URL, URLClassLoader
        from java.lang import ClassLoader
        from java.io import File
        m = URLClassLoader.getDeclaredMethod("addURL", [URL])
        m.accessible = 1
        m.invoke(ClassLoader.getSystemClassLoader(), [File(jarFile).toURL()])
    
    importJar("opendmk_jmxremote_optional_jar-1.0-b01-ea.jar")
    
    from javax.management.remote import JMXServiceURL
    from javax.management.remote import JMXConnector
    from javax.management.remote import JMXConnectorFactory
    
    jmx_url = JMXServiceURL("service:jmx:jmxmp://server:port/")
    jmx_connector = JMXConnectorFactory.connect(jmx_url)
    
    

    【讨论】:

      【解决方案3】:

      另一种选择可能是使用不同的堆栈,例如 Jolokia,它通过 HTTP 和 JSON 导出 JMX 信息。尽管还没有 Python,但已经有各种客户端绑定(Perl 通过Jmx4Perl、Javascript、Java)。但是从头开始构建应该不难,协议在here有详细描述。

      【讨论】:

        猜你喜欢
        • 2014-05-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-02
        相关资源
        最近更新 更多