Gọi phương thức JMX MBean từ một tập lệnh shell


98

Có thư viện nào cho phép tôi gọi phương thức JMX MBean từ tập lệnh shell không. Chúng tôi hiển thị một số hoạt động / lệnh quản trị thông qua JMX và chúng tôi có thể yêu cầu quản trị viên sử dụng JConsole hoặc VisualVM, nhưng một số tác vụ tốt hơn nên để tự động hóa. Trong quá trình tự động hóa đó, chúng tôi muốn có thể gọi một phương thức JMX MBean trên máy chủ đang chạy của chúng tôi, tốt nhất là từ một tập lệnh shell.

Câu trả lời:


106

Các tiện ích JMX dòng lệnh sau có sẵn:

  1. jmxterm - dường như là tiện ích đầy đủ tính năng nhất.
  2. cmdline-jmxclient - được sử dụng trong dự án WebArchive có vẻ rất trơ trọi (và không có sự phát triển nào kể từ năm 2006)
  3. Tập lệnh Groovy và JMX - cung cấp một số chức năng JMX thực sự mạnh mẽ nhưng yêu cầu thiết lập thư viện linh hoạt và khác.
  4. Chức năng dòng lệnh JManage - (nhược điểm là nó yêu cầu máy chủ JManage đang chạy để proxy các lệnh thông qua)

Ví dụ về 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();

Ví dụ về cmdline-jmxclient:

Nếu bạn có một

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

Với một Hoạt động được gọi là:

  • jmxForceRefresh ()

Sau đó, bạn có thể viết một tập lệnh bash đơn giản (giả sử bạn tải xuống cmdline-jmxclient-0.10.3.jar và đặt trong cùng một thư mục với tập lệnh của bạn):

#!/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

jmxterm dường như không làm việc trên Java 7 bugs.launchpad.net/jmxterm/+bug/942693
artbristol

19

Tôi đã phát triển jmxfuse cho thấy JMX Mbeans là một hệ thống tệp FUSE Linux với chức năng tương tự như / proc fs. Nó dựa vào Jolokia làm cầu nối với JMX. Các thuộc tính và hoạt động được hiển thị để đọc và ghi.

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

Ví dụ, để đọc một thuộc tính:

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

để viết một thuộc tính:

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

để gọi một hoạt động:

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

12

Các Plugin Syabru Nagios JMX có nghĩa là để được sử dụng từ Nagios, nhưng không đòi hỏi Nagios và rất thuận tiện cho việc sử dụng dòng lệnh:

~$ ./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;;;;

Điều này là tuyệt vời, và rất nhanh chóng. Khoảng 0,3 giây để trả về giá trị so với 3 giây cho jmxterm
sivann

9

Có thể dễ dàng nhất để viết điều này bằng 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[]{})


    }

}

Điều này sẽ biên dịch thành một .class duy nhất và không cần phụ thuộc vào máy chủ hoặc bất kỳ đóng gói maven phức tạp nào.

gọi nó bằng

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

4

Một chút rủi ro, nhưng bạn có thể chạy lệnh curl POST với các giá trị từ biểu mẫu từ bảng điều khiển JMX, xác thực URL và http của nó (nếu cần):

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

Lưu ý: chỉ mục phương pháp có thể thay đổi khi có những thay đổi đối với phần mềm. Và việc triển khai biểu mẫu web có thể thay đổi.

Ở trên dựa trên nguồn của trang dịch vụ JMX cho thao tác bạn muốn thực hiện:

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

Nguồn của biểu mẫu:

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>

Tôi đã triển khai nó theo cách này từ Java bằng cách sử dụng a HttpURLConnectionvà tôi có thể xác nhận rằng nó hoạt động. (btw. submit=Invokelà không cần thiết)
tom

là nó có thể để mô tả nó hoạt động như thế nào? Ý tôi là, theo mặc định jmx sử dụng rmi, và tôi thấy ở đó http. Nó có nghĩa là máy chủ phải được cấu hình để hỗ trợ các yêu cầu jmx http?
Psychozoic

3

Hãy xem JManage . Nó có thể thực thi các phương thức MBean và lấy / đặt các thuộc tính từ dòng lệnh .


Nhược điểm duy nhất là sử dụng tiện ích dòng lệnh, nó yêu cầu JManage chạy các lệnh proxy đến máy chủ JMX của bạn. Tôi muốn có một cách tiếp cận nhẹ hơn trực tiếp đến chính máy chủ JMX.
Dougnukem

3

Bạn cũng có thể muốn xem jmx4perl . Nó cung cấp quyền truy cập không cần java vào MBeans của Máy chủ Java EE từ xa. Tuy nhiên, một servlet tác nhân nhỏ cần được cài đặt trên nền tảng đích, nền tảng này cung cấp Quyền truy cập JMX hiệu quả qua HTTP với tải trọng JSON. (Phiên bản 0.50 sẽ thêm chế độ không tác nhân bằng cách triển khai proxy JSR-160).

Ưu điểm là thời gian khởi động nhanh so với khởi chạy java JVM cục bộ và dễ sử dụng. jmx4perl đi kèm với một bộ đầy đủ các mô-đun Perl có thể dễ dàng sử dụng trong các tập lệnh của riêng bạn:

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

Bạn cũng có thể sử dụng bí danh cho các tổ hợp MBean / Thuộc tính / Hoạt động phổ biến (ví dụ: đối với hầu hết MXBeans). Đối với các tính năng bổ sung (Nagios-Plugin, truy cập giống XPath vào các loại thuộc tính phức tạp, ...), vui lòng tham khảo tài liệu của jmx4perl.


1

Câu trả lời của @Dougnukem đã giúp tôi rất nhiều. Tôi đã sử dụng phương pháp Groovy (sử dụng groovy 2.3.3).

Tôi đã thực hiện một số thay đổi trên mã Dougnukem. Điều này sẽ hoạt động với Java 7 và sẽ in hai thuộc tính ra stdout sau mỗi 10 giây.

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

                }
            }

Biên dịch mã này thành một jar bằng cách sử dụng maven-compiler-plugin, do đó bạn sẽ không yêu cầu cài đặt groovy chỉ groovy-all.jar. Dưới đây là định nghĩa và phụ thuộc plugin có liên quan.

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

Bọc nó bằng một con dơi hoặc một cái vỏ và nó sẽ in dữ liệu ra stdout.


0

Tôi không chắc về môi trường giống như bash. Bạn có thể thử một số chương trình trình bao bọc đơn giản trong Java (với các đối số chương trình) gọi MBeans của bạn trên máy chủ từ xa. Sau đó, bạn có thể gọi các trình bao bọc này từ tập lệnh shell

Nếu bạn có thể sử dụng thứ gì đó như Python hoặc Perl, bạn có thể quan tâm đến JSR-262 cho phép bạn hiển thị các hoạt động JMX trên các dịch vụ web. Điều này được lên lịch để đưa vào Java 7 nhưng bạn có thể sử dụng một ứng cử viên phát hành của triển khai tham chiếu

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.