JMXを使用してlocalhost jvmのJavaプログラムに接続する必要があります。言い換えると、localhostのJavaプログラムを設定するJMXクライアントを開発したいです。
JConsoleの使用はお勧めしません! JConsoleは一般的なJMXクライアントであり、メインプログラムのパフォーマンスに悪影響を及ぼすため、適切ではありません。
OracleサイトのサンプルではRMIConnectorとHost:port paramsを使用していますが、わかりません。jmxポートをどこに設定すればよいですか?
JConsoleには、JavaプロセスをPIDで接続するオプションがあります。しかし、入力パラメータとしてPIDを持つメソッドがJMX APIに見つかりません。
次のようなものを使用して、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 landから実行する必要があります。次のコードは使用していませんが、機能しているようです。
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();
}
}
私は SimpleJMXパッケージ の著者でもあります。これにより、JMXサーバーの起動とBeanのリモートクライアントへの公開が容易になります。
// 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月)。
明確にするために、ローカルJMX統計の取得のみに関心がある場合は、リモートAPIを使用する必要はありません。 Java.lang.management.ManagementFactory
を使用するだけです:
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
memoryMXBean.getHeapMemoryUsage().getMax();
...
List<MemoryPoolMXBean> beans = ManagementFactory.getMemoryPoolMXBeans();
...
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以降を使用するプログラムにのみ適用可能。
最も簡単な手段:
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) ...
}