2011-04-05 2 views
35

JMX를 사용하여 localhost jvm의 Java 프로그램에 연결해야합니다. 즉, localhost에 자바 프로그램을 설정하기 위해 JMX 클라이언트를 개발하려고합니다.JMX를 사용하여 localhost jvm에서 Java 프로그램에 연결하는 방법은 무엇입니까?

  • JConsole을 사용하지 않는 것이 좋습니다! JConsole은 일반적인 JMX 클라이언트이고 주 프로그램 성능에 부정적인 영향을주기 때문에 JConsole은 적합하지 않습니다.

  • oracle 사이트의 샘플은 RMIConnector와 host : port 매개 변수를 사용하지만 잘 모르겠습니다. 여기서 jmx 포트를 설정해야합니까?

  • JConsole에는 PID로 java 프로세스에 연결할 수있는 옵션이 있습니다. 하지만 PID를 입력 매개 변수로 가지는 JMX API에서는 메소드를 찾지 못했습니다.

+1

모두 메인 프로그램과 JMX 클라이언트가 독립 실행 형 프로그램 (자바 SE를)입니다. – mjafari

+0

http://www.pongasoft.com/blog/yan/entry/connecting_to_a_local_vm/ –

답변

56

우리는 JMX 서버에 프로그래밍 방식으로 연결하기 위해 다음과 같은 것을 사용합니다. 그런 다음 서버에 연결할 수

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

:

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

특정 주소로 바인딩하려면 다음과 같은 VM 인수를 추가해야합니다 : 당신은 다음 인수와 같은 뭔가 서버를 실행해야합니다 다음과 같이 JMX 클라이언트 코드를 사용하여 : 우리는 또한 프로그래밍 방식 VM 인수 이외의 특정 포트에 자신을 게시 할 수있는 코드를 가지고 있지만 더 푸의

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

네가 필요 이상으로 생각한다.


"pid로"연결하는 관점에서, 내가 아는 한 Java6에서 Java6을 사용해야합니다. 다음 코드는 사용하지 않았지만 제대로 작동하는 것 같습니다.

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

I했습니다 또한 쉽게 JMX 서버를 시작하고 원격 클라이언트에 콩을 게시 할 수 있습니다 SimpleJMX package의 저자.

// 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에 의해 프로세스를 찾을 수있는 메커니즘이없는 클라이언트 인터페이스를 가지고있다 - 단지 호스트/포트 조합이 지원됩니다 (2,012분의 6 년).

+1

감사합니다. 회색을 참조하십시오. 당신 (또는 다른 사람들)이 나의 두 번째 질문 (PID를 사용하는 로컬 jmx 연결)에 대답 할 수 있습니까? – mjafari

+0

어떤 이유인지 ConnectorAddress가 null 인 경우 에이전트를 동적으로로드하려고 시도 할 수 있습니다. http://www.pongasoft.com/blog/yan/entry/connecting_to_a_local_vm/ –

+0

줄에 다음과 같은 컴파일 문제가 있습니다. jmxConnector.close(); – shlomi33

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 이상을 사용하는 프로그램에만 적용 가능)

4

로컬 JMX 통계를 얻는 데 관심이있는 경우 원격 API를 사용할 필요가 없습니다. java.lang.management.ManagementFactory :

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

List<MemoryPoolMXBean> beans = ManagementFactory.getMemoryPoolMXBeans(); 
... 
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) ... 
}