Jak połączyć się z programem java na localhost jvm za pomocą JMX?

Powinienem połączyć się z programem java na localhost jvm używając JMX. Innymi słowy chcę stworzyć klienta JMX do konfiguracji programu java na localhost.

  • Nie polecam używania JConsole! JConsole nie jest odpowiedni, ponieważ jest ogólnym klientem JMX i ma negatywny wpływ na wydajność głównego programu.

  • Sample na stronie oracle używają RMIConnector i host:port params ale nie wiem: gdzie należy ustawić port jmx?

  • JConsole ma możliwość połącz się z procesami java przez PID. Ale nie znajduję żadnej metody w JMX api, która ma PID jako param wejściowy.

Author: mjafari, 2011-04-05

4 answers

Używamy czegoś takiego jak poniżej, aby programowo połączyć się z naszymi serwerami JMX. Powinieneś uruchomić swój serwer z czymś w rodzaju następujących argumentów:

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

Aby powiązać konkretny adres, musisz dodać następujące argumenty maszyny wirtualnej:

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

Następnie możesz połączyć się z serwerem za pomocą kodu klienta JMX w następujący sposób:

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

Mamy również kod, który może programowo publikować się do określonego portu poza argumentami VM, ale to więcej myślę, że fu, niż potrzebujesz.


Jeśli chodzi o łączenie "przez pid", musisz używać Java6, aby zrobić to z ziemi Javy, o ile wiem. Nie użyłem poniższego kodu, ale wydaje się, że działa.

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

Jestem również autorem pakietu SimpleJMX , który ułatwia uruchomienie serwera JMX i publikowanie fasoli do zdalnych klientów.

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

Posiada również interfejs klienta, ale w tej chwili nie ma żadnych mechanizmów do znajdowania procesów za pomocą PID-tylko obsługiwane są kombinacje host/port (w 6/2012).

 60
Author: Gray,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-22 21:02:34

Aby wyjaśnić, jeśli jesteś zainteresowany tylko uzyskaniem lokalnych statystyk JMX, nie musisz używać zdalnego api. Wystarczy użyć java.lang.management.ManagementFactory:

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

List<MemoryPoolMXBean> beans = ManagementFactory.getMemoryPoolMXBeans();
...
 4
Author: cwu9T9,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-18 12:55:46
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;
}

Wymaga to użycia argumentu jmxremote podczas uruchamiania JVM dla procesu, który próbujesz odczytać. Aby móc to zrobić bez konieczności przekazywania argumentu jmxremote przy starcie. Będziesz musiał użyć API attached (dotyczy tylko programów używających Java 6 i wyższych.

 3
Author: Umang Desai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-30 03:11:12

Najprostsze znaczy:

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) ...
}
 1
Author: berhauz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-07 16:04:40