Java 从 shell 脚本调用 JMX MBean 方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1751130/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 22:17:39  来源:igfitidea点击:

Calling JMX MBean method from a shell script

javasysadminjmx

提问by Dougnukem

Are there any libraries that would allow me to call a JMX MBean method from a shell script. We expose some operations/admin commands through JMX, and we could have our admins use JConsole, or VisualVM, but some tasks are better left to automation. In that automation we'd like to be able to call a JMX MBean method on our running server, preferably from a shell script.

是否有任何库允许我从 shell 脚本调用 JMX MBean 方法。我们通过 JMX 公开一些操作/管理命令,我们可以让我们的管理员使用 JConsole 或 VisualVM,但有些任务最好留给自动化。在该自动化中,我们希望能够在我们正在运行的服务器上调用 JMX MBean 方法,最好是从 shell 脚本调用。

采纳答案by Dougnukem

The following command line JMX utilities are available:

以下命令行 JMX 实用程序可用:

  1. jmxterm- seems to be the most fully featured utility.
  2. cmdline-jmxclient- used in the WebArchive project seems very bare bones (and no development since 2006 it looks like)
  3. Groovy script and JMX- provides some really powerful JMX functionality but requires groovy and other library setup.
  4. JManage command line functionality- (downside is that it requires a running JManage server to proxy commands through)
  1. jmxterm- 似乎是功能最齐全的实用程序。
  2. cmdline-jmxclient- 在 WebArchive 项目中使用似乎非常简单(并且自 2006 年以来没有开发它看起来像)
  3. Groovy 脚本和 JMX- 提供了一些非常强大的 JMX 功能,但需要 groovy 和其他库设置。
  4. JManage 命令行功能- (缺点是它需要一个正在运行的 JManage 服务器来代理命令)

Groovy JMX Example:

Groovy JMX 示例:

import java.lang.management.*
import javax.management.ObjectName
import javax.management.remote.JMXConnectorFactory as JmxFactory
import javax.management.remote.JMXServiceURL as JmxUrl

def serverUrl = 'service:jmx:rmi:///jndi/rmi://localhost:9003/jmxrmi'
String beanName = "com.webwars.gameplatform.data:type=udmdataloadsystem,id=0"
def server = JmxFactory.connect(new JmxUrl(serverUrl)).MBeanServerConnection
def dataSystem = new GroovyMBean(server, beanName)

println "Connected to:\n$dataSystem\n"

println "Executing jmxForceRefresh()"
dataSystem.jmxForceRefresh();

cmdline-jmxclient example:

cmdline-jmxclient 示例:

If you have an

如果你有一个

  • MBean: com.company.data:type=datasystem,id=0
  • MBean:com.company.data:type=datasystem,id=0

With an Operation called:

使用名为的操作:

  • jmxForceRefresh()
  • jmxForceRefresh()

Then you can write a simple bash script (assuming you download cmdline-jmxclient-0.10.3.jarand put in the same directory as your script):

然后你可以编写一个简单的 bash 脚本(假设你下载了cmdline-jmxclient-0.10.3.jar并放在与你的脚本相同的目录中):

#!/bin/bash

cmdLineJMXJar=./cmdline-jmxclient-0.10.3.jar
user=yourUser
password=yourPassword
jmxHost=localhost
port=9003

#No User and password so pass '-'
echo "Available Operations for com.company.data:type=datasystem,id=0"
java -jar ${cmdLineJMXJar} ${user}:${password} ${jmxHost}:${port} com.company.data:type=datasystem,id=0

echo "Executing XML update..."
java -jar ${cmdLineJMXJar} - ${jmxHost}:${port} com.company.data:type=datasystem,id=0 jmxForceRefresh

回答by Kevin

I'm not sure about bash-like environment. You might try some simple wrapper programs in Java (with program arguments) that invoke your MBeans on the remote server. You can then call these wrappers from the shell script

我不确定类似 bash 的环境。您可以尝试在 Java 中使用一些简单的包装程序(带有程序参数)来调用远程服务器上的 MBean。然后您可以从 shell 脚本调用这些包装器

If you can use something like Python or Perl, you might be interested in JSR-262which allows you to expose JMX operations over web services. This is scheduled to be included in Java 7 but you might be able to use a release candidate of the reference implementation

如果您可以使用 Python 或 Perl 之类的东西,您可能会对JSR-262感兴趣,它允许您通过 Web 服务公开 JMX 操作。这计划包含在 Java 7 中,但您可以使用参考实现的候选版本

回答by ChssPly76

Take a look at JManage. It's able to execute MBean methods and get / set attributes from command line.

看看JManage。它能够执行 MBean 方法并从命令行获取/设置属性。

回答by Roland Hu?

You might want also to have a look at jmx4perl. It provides java-less access to a remote Java EE Server's MBeans. However, a small agent servlet needs to be installed on the target platform, which provides a restful JMX Access via HTTP with a JSON payload. (Version 0.50 will add an agentless mode by implementing a JSR-160 proxy).

您可能还想看看jmx4perl。它提供对远程 Java EE 服务器的 MBean 的无 Java 访问。但是,需要在目标平台上安装一个小型代理 servlet,它通过带有 JSON 有效负载的 HTTP 提供一个安静的 JMX 访问。(0.50 版将通过实现 JSR-160 代理添加无代理模式)。

Advantages are quick startup times compared to launching a local java JVM and ease of use. jmx4perl comes with a full set of Perl modules which can be easily used in your own scripts:

与启动本地 java JVM 相比,优点是启动时间快且易于使用。jmx4perl 带有一整套 Perl 模块,可以在您自己的脚本中轻松使用:

use JMX::Jmx4Perl;
use JMX::Jmx4Perl::Alias;   # Import certains aliases for MBeans

print "Memory Used: ",
      JMX::Jmx4Perl
          ->new(url => "http://localhost:8080/j4p")
          ->get_attribute(MEMORY_HEAP_USED);

You can also use alias for common MBean/Attribute/Operation combos (e.g. for most MXBeans). For additional features (Nagios-Plugin, XPath-like access to complex attribute types, ...), please refer to the documentation of jmx4perl.

您还可以为常见的 MBean/属性/操作组合使用别名(例如,对于大多数 MXBean)。有关其他功能(Nagios-Plugin、类似 XPath 的复杂属性类型访问等),请参阅 jmx4perl 的文档。

回答by Austin Mills

The Syabru Nagios JMX pluginis meant to be used from Nagios, but doesn't require Nagios and is very convenient for command-line use:

Syabru Nagios的JMX插件是为了从Nagios的使用,但不要求Nagios的,是命令行使用非常方便:

~$ ./check_jmx -U service:jmx:rmi:///jndi/rmi://localhost:1099/JMXConnector --username myuser --password mypass -O java.lang:type=Memory -A HeapMemoryUsage -K used 
JMX OK - HeapMemoryUsage.used = 445012360 | 'HeapMemoryUsage used'=445012360;;;;

回答by Alastair McCormack

I've developed jmxfuse which exposes JMX Mbeans as a Linux FUSE filesystem with similar functionality as the /proc fs. It relies on Jolokiaas the bridge to JMX. Attributes and operations are exposed for reading and writing.

我开发了 jmxfuse,它将 JMX Mbeans 公开为具有与 /proc fs 类似功能的 Linux FUSE 文件系统。它依赖Jolokia作为连接 JMX 的桥梁。属性和操作被公开用于读取和写入。

http://code.google.com/p/jmxfuse/

http://code.google.com/p/jmxfuse/

For example, to read an attribute:

例如,读取一个属性:

me@oddjob:jmx$ cd log4j/root/attributes
me@oddjob:jmx$ cat priority

to write an attribute:

写一个属性:

me@oddjob:jmx$ echo "WARN" > priority

to invoke an operation:

调用操作:

me@oddjob:jmx$ cd Catalina/none/none/WebModule/localhost/helloworld/operations/addParameter
me@oddjob:jmx$ echo "myParam myValue" > invoke

回答by BBay

A little risky, but you could run a curl POST command with the values from the form from the JMX console, its URL and http authentication (if required):

有点冒险,但您可以使用来自 JMX 控制台的表单中的值、其 URL 和 http 身份验证(如果需要)运行 curl POST 命令:

curl -s -X POST --user 'myuser:mypass'
  --data "action=invokeOp&name=App:service=ThisServiceOp&methodIndex=3&arg0=value1&arg1=value1&submit=Invoke"
  http://yourhost.domain.com/jmx-console/HtmlAdaptor

Beware: the method index may change with changes to the software. And the implementation of the web form could change.

注意:方法索引可能会随着软件的变化而变化。并且 Web 表单的实现可能会发生变化。

The above is based on source of the JMX service page for the operation you want to perform:

以上基于您要执行的操作的 JMX 服务页面的来源:

http://yourhost.domain.com/jmx-console/HtmlAdaptor?action=inspectMBean&name=YourJMXServiceName

Source of the form:

表格来源:

form method="post" action="HtmlAdaptor">
   <input type="hidden" name="action" value="invokeOp">
   <input type="hidden" name="name" value="App:service=ThisServiceOp">
   <input type="hidden" name="methodIndex" value="3">
   <hr align='left' width='80'>
   <h4>void ThisOperation()</h4>
   <p>Operation exposed for management</p>
    <table cellspacing="2" cellpadding="2" border="1">
        <tr class="OperationHeader">
            <th>Param</th>
            <th>ParamType</th>
            <th>ParamValue</th>
            <th>ParamDescription</th>
        </tr>
        <tr>
            <td>p1</td>
           <td>java.lang.String</td>
         <td> 
            <input type="text" name="arg0">
         </td>
         <td>(no description)</td>
        </tr>
        <tr>
            <td>p2</td>
           <td>arg1Type</td>
         <td> 
            <input type="text" name="arg1">
         </td>
         <td>(no description)</td>
        </tr>
    </table>
    <input type="submit" value="Invoke">
</form>

回答by Haim Raman

@Dougnukem answer helped me a lot. I have taken the Groovy approach (using groovy 2.3.3).

@Dougnukem 的回答对我帮助很大。我采用了 Groovy 方法(使用 groovy 2.3.3)。

I did some changes on Dougnukem code. This will work with Java 7 and will print two attributes to stdout every 10 sec.

我对 Dougnukem 代码做了一些更改。这将适用于 Java 7,并将每 10 秒向 stdout 打印两个属性。

        package com.my.company.jmx
        import groovy.util.GroovyMBean;
        import javax.management.remote.JMXServiceURL
        import javax.management.remote.JMXConnectorFactory
        import java.lang.management.*

            class Monitor {
                static main(args) {
                    def serverUrl = 'service:jmx:rmi:///jndi/rmi://localhost:5019/jmxrmi'
                    String beanName = "Catalina:type=DataSource,class=javax.sql.DataSource,name=\"jdbc/CommonDB\""
                    println  "numIdle,numActive"

                    while(1){
                        def server = JMXConnectorFactory.connect(new JMXServiceURL(serverUrl))
                       //make sure to reconnect in case the jvm was restrated 
                        server.connect()
                        GroovyMBean mbean = new GroovyMBean(server.MBeanServerConnection, beanName)
                        println  "${mbean.numIdle},${mbean.numActive}"
                        server.close()
                        sleep(10000)
                    }

                }
            }

Compile this code into a jar using maven-compiler-plugin so you will not require groovy installation only the groovy-all.jar . Below is the relevant plugin definition and dependency.

使用 maven-compiler-plugin 将此代码编译到 jar 中,这样您就不需要 groovy 安装,只需要 groovy-all.jar 。下面是相关的插件定义和依赖。

   <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <compilerId>groovy-eclipse-compiler</compilerId>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.codehaus.groovy</groupId>
                        <artifactId>groovy-eclipse-compiler</artifactId>
                        <version>2.8.0-01</version>
                    </dependency>
                    <dependency>
                        <groupId>org.codehaus.groovy</groupId>
                        <artifactId>groovy-eclipse-batch</artifactId>
                        <version>2.3.4-01</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.4.3</version>
        </dependency>
    </dependencies>

Wrap it with a bat or a shell and it will print the data to stdout.

用蝙蝠或外壳包裹它,它会将数据打印到标准输出。

回答by teknopaul

Potentially its easiest to write this in Java

用 Java 编写它可能是最简单的

import javax.management.*;
import javax.management.remote.*;

public class JmxInvoke {

    public static void main(String... args) throws Exception {

        JMXConnectorFactory.connect(new JMXServiceURL(args[0]))
            .getMBeanServerConnection().invoke(new ObjectName(args[1]), args[2], new Object[]{}, new String[]{})


    }

}

This would compile to a single .class and needs no dependencies in server or any complicated maven packaging.

这将编译为单个 .class 并且不需要服务器或任何复杂的 maven 打包中的依赖项。

call it with

用它来称呼它

javac JmxInvoke.java
java -cp . JmxInvoke [url] [beanName] [method]