从 shell 脚本调用 JMX MBean 方法

发布于 2024-08-11 03:15:18 字数 1804 浏览 11 评论 0 原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

我做我的改变 2024-08-18 03:15:18

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

  1. jmxterm - 似乎是功能最齐全的实用程序。
  2. cmdline-jmxclient - 在 WebArchive 项目中使用似乎非常简单(自 2006 年以来没有任何开发)看起来像)
  3. Groovy 脚本和 JMX - 提供了一些非常强大的 JMX 功能,但是需要 groovy 和其他库设置。
  4. JManage 命令行
    功能
    - (缺点是
    它需要一个正在运行的 JManage
    服务器通过代理命令)

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 示例:

如果您有一个

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

操作名为:

  • jmxForceRefresh()

然后您可以编写一个简单的 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

The following command line JMX utilities are available:

  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)

Groovy JMX Example:

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:

If you have an

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

With an Operation called:

  • jmxForceRefresh()

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

#!/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
佞臣 2024-08-18 03:15:18

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

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

例如,读取属性:

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

编写属性:

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

调用操作:

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

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

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
许一世地老天荒 2024-08-18 03:15:18

用 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[]{});    
    }

}

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

调用它

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

Potentially its easiest to write this in 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.

call it with

javac JmxInvoke.java
java -cp . JmxInvoke [url] [beanName] [method]
很快妥协 2024-08-18 03:15:18

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;;;;

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

~$ ./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;;;;
泪冰清 2024-08-18 03:15:18

有一点风险,但您可以使用 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

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

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

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

表单来源:

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>

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):

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.

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

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>
淑女气质 2024-08-18 03:15:18

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

与启动本地 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);

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

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).

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:

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.

囚我心虐我身 2024-08-18 03:15:18

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

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

与他有关 2024-08-18 03:15:18

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

我对 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)
                    }

                }
            }

使用 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>

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

@Dougnukem answer helped me a lot. I have taken the Groovy approach (using 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.

        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.

   <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.

把时间冻结 2024-08-18 03:15:18

以下步骤描述了从命令行使用 jmxterm

首先,下载 jmxterm JAR 文件

omega@omega-master-0:/opt/omega/data/backup$ wget https://github.com/jiaqi/jmxterm/releases/download/v1.0.4/jmxterm-1.0.4-uber.jar

运行 jmxterm

omega@omega-master-0:/opt/omega/data/backup$ java -jar jmxterm-1.0.4-uber.jar

打开连接

gt;open localhost:9999
#Connection to localhost:9999 is opened

列出所有 JMX beans

gt;beans
#domain = JMImplementation:
JMImplementation:type=MBeanServerDelegate
...
java.lang:type=Memory
java.lang:type=OperatingSystem
java.lang:type=Runtime
...

通过运行如下命令查看 bean 的统计信息。

gt;get -b java.lang:type=Memory *
#mbean = java.lang:type=Memory:
Verbose = false;

ObjectPendingFinalizationCount = 0;

HeapMemoryUsage = { 
  committed = 4143972352;
  init = 526385152;
  max = 4143972352;
  used = 2113527712;
 };

NonHeapMemoryUsage = { 
  committed = 371900416;
  init = 2555904;
  max = -1;
  used = 320582904;
 };

ObjectName = java.lang:type=Memory;

Below steps describe using jmxterm from command line.

First, download jmxterm JAR file

omega@omega-master-0:/opt/omega/data/backup$ wget https://github.com/jiaqi/jmxterm/releases/download/v1.0.4/jmxterm-1.0.4-uber.jar

Run jmxterm

omega@omega-master-0:/opt/omega/data/backup$ java -jar jmxterm-1.0.4-uber.jar

Open a connection

gt;open localhost:9999
#Connection to localhost:9999 is opened

List all JMX beans

gt;beans
#domain = JMImplementation:
JMImplementation:type=MBeanServerDelegate
...
java.lang:type=Memory
java.lang:type=OperatingSystem
java.lang:type=Runtime
...

See the stats for a bean by running command like below.

gt;get -b java.lang:type=Memory *
#mbean = java.lang:type=Memory:
Verbose = false;

ObjectPendingFinalizationCount = 0;

HeapMemoryUsage = { 
  committed = 4143972352;
  init = 526385152;
  max = 4143972352;
  used = 2113527712;
 };

NonHeapMemoryUsage = { 
  committed = 371900416;
  init = 2555904;
  max = -1;
  used = 320582904;
 };

ObjectName = java.lang:type=Memory;
空名 2024-08-18 03:15:18

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

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

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

If you can use something like Python or Perl, you might be interested in JSR-262 which 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

淡墨 2024-08-18 03:15:18

扩展上述Java答案并添加支持“newTrade”为字符串的参数

    JMXConnectorFactory.connect(new JMXServiceURL(url))
            .getMBeanServerConnection()
            .invoke(new ObjectName(beanName), methodName, new Object[]{newTrade}, new String[]{String.class.getName()});

Expanding on the above Java answer and adding support for a parameter where 'newTrade' is a String

    JMXConnectorFactory.connect(new JMXServiceURL(url))
            .getMBeanServerConnection()
            .invoke(new ObjectName(beanName), methodName, new Object[]{newTrade}, new String[]{String.class.getName()});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文