44

JMX を使用して、localhost jvm 上の Java プログラムに接続する必要があります。つまり、JMX クライアントを開発して、localhost で Java プログラムを構成したいと考えています。

  • JConsole の使用はお勧めしません。JConsole は一般的な JMX クライアントであり、メイン プログラムのパフォーマンスに悪影響を及ぼすため、適していません。

  • Oracle サイトのサンプルでは RMIConnector と host:port パラメータを使用していますが、わかりません: jmx ポートをどこに設定すればよいですか?

  • JConsole には、PID によって Java プロセスに接続するオプションがあります。しかし、入力パラメーターとして PID を持つ JMX API のメソッドが見つかりません。

4

5 に答える 5

64

次のようなものを使用して、JMX サーバーにプログラムで接続します。次のような引数を使用してサーバーを実行する必要があります。

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.port=1234
-Dcom.sun.management.jmxremote.ssl=false

特定のアドレスにバインドするには、次の VM 引数を追加する必要があります。

-Djava.rmi.server.hostname=A.B.C.D

次に、次のような JMX クライアント コードを使用してサーバーに接続できます。

String host = "localhost";  // or some A.B.C.D
int port = 1234;
String url = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi";
JMXServiceURL serviceUrl = new JMXServiceURL(url);
JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceUrl, null);
try {
   MBeanServerConnection mbeanConn = jmxConnector.getMBeanServerConnection();
   // now query to get the beans or whatever
   Set<ObjectName> beanSet = mbeanConn.queryNames(null, null);
   ...
} finally {
   jmxConnector.close();
}

VM引数の外にある特定のポートにプログラムで公開できるコードもありますが、それは必要以上に面倒です。


「pidによる」接続に関しては、私の知る限り、Java6を使用してJavaランドから接続する必要があります。次のコードは使用していませんが、機能しているようです。

List<VirtualMachineDescriptor> vms = VirtualMachine.list();
for (VirtualMachineDescriptor desc : vms) {
    VirtualMachine vm;
    try {
        vm = VirtualMachine.attach(desc);
    } catch (AttachNotSupportedException e) {
        continue;
    }
    Properties props = vm.getAgentProperties();
    String connectorAddress =
        props.getProperty("com.sun.management.jmxremote.localConnectorAddress");
    if (connectorAddress == null) {
        continue;
    }
    JMXServiceURL url = new JMXServiceURL(connectorAddress);
    JMXConnector connector = JMXConnectorFactory.connect(url);
    try {
        MBeanServerConnection mbeanConn = connector.getMBeanServerConnection();
        Set<ObjectName> beanSet = mbeanConn.queryNames(null, null);
        ...
    } finally {
        jmxConnector.close();
    }
}

また、JMX サーバーの起動とリモート クライアントへの Bean の発行を簡単にするSimpleJMX パッケージの作成者でもあります。

// create a new server listening on port 8000
JmxServer jmxServer = new JmxServer(8000);
// start our server
jmxServer.start();
// register our lookupCache object defined below
jmxServer.register(lookupCache);
jmxServer.register(someOtherObject);
// stop our server
jmxServer.stop();

クライアント インターフェイスも備えていますが、現時点では PID でプロセスを検索するメカニズムはありません。ホストとポートの組み合わせのみがサポートされています (2012 年 6 月)。

于 2011-04-05T16:16:36.317 に答える
6

明確にするために、ローカル JMX 統計の取得のみに関心がある場合は、リモート API を使用する必要はありません。使用するだけjava.lang.management.ManagementFactoryです:

MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
memoryMXBean.getHeapMemoryUsage().getMax();
...

List<MemoryPoolMXBean> beans = ManagementFactory.getMemoryPoolMXBeans();
...
于 2013-01-29T16:57:25.117 に答える
3
List<VirtualMachineDescriptor> vm = new ArrayList<VirtualMachineDescriptor>();
        jvmList = new JVMListManager();

        vm = jvmList.listActiveVM();

        for (VirtualMachineDescriptor vmD : vm) 
        {
            try
            {

            //importFrom is taking a process ID and returning a service url in a String Format
            String ServiceUrl = ConnectorAddressLink.importFrom(Integer.parseInt(vmD.id().trim()));
            JMXServiceURL jmxServiceUrl = new JMXServiceURL(ServiceUrl);

            jmxConnector = JMXConnectorFactory.connect(jmxServiceUrl, null);
            con = jmxConnector.getMBeanServerConnection();
            CompilationMXBean compMXBean = ManagementFactory.newPlatformMXBeanProxy(con
                   , ManagementFactory.COMPILATION_MXBEAN_NAME
                   , CompilationMXBean.class);
            }catch(Exception e)
            {
            //Do Something  
            }
        }


protected List listActiveVM() {
    List<VirtualMachineDescriptor> vm = VirtualMachine.list();

    return vm;
}

これには、読み取ろうとしているプロセスの JVM 起動時に jmxremote 引数を使用する必要があります。起動時に jmxremote 引数を渡さなくても実行できるようにします。アタッチ API を使用する必要があります (Java 6 以降を使用するプログラムにのみ適用されます。

于 2012-12-28T09:51:19.690 に答える
1

最も簡単な手段:

import javax.management.Attribute;
import javax.management.AttributeList;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;

// set a self JMX connection
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
// set the object name(s) you are willing to query, here a CAMEL JMX object
ObjectName objn = new ObjectName("org.apache.camel:context=*,type=routes,name=\"route*\"");
Set<ObjectName> objectInstanceNames = mBeanServer.queryNames(objn, null);
for (ObjectName on : objectInstanceNames) {
    // query a number of attributes at once
    AttributeList attrs = mBeanServer.getAttributes(on, new String[] {"ExchangesCompleted","ExchangesFailed"});
    // process attribute values (beware of nulls...)
    // ... attrs.get(0) ... attrs.get(1) ...
}
于 2016-11-07T16:04:40.967 に答える