habilitar enable activar java localhost rmi jmx jconsole

java - enable - jconsole tomcat



Cómo conectarse a un programa Java en localhost jvm usando JMX? (4)

El más simple significa:

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

Debería conectarme a un programa java en localhost jvm usando JMX. En otras palabras, quiero desarrollar un cliente JMX para configurar un programa Java en localhost.

  • ¡No recomiendo usar JConsole! JConsole no es adecuado porque es un cliente JMX general y tiene un efecto negativo en el rendimiento del programa principal.

  • Las muestras en el sitio Oracle usan RMIConnector y host: params de puerto pero no sé: ¿dónde debería establecer el puerto jmx?

  • JConsole tiene una opción para conectarse a procesos Java mediante PID. Pero no encuentro ningún método en JMX api que tenga PID como parámetro de entrada.


Para aclarar, si solo está interesado en obtener estadísticas locales de JMX, no necesita usar la API remota. Simplemente use java.lang.management.ManagementFactory :

MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean(); memoryMXBean.getHeapMemoryUsage().getMax(); ... List<MemoryPoolMXBean> beans = ManagementFactory.getMemoryPoolMXBeans(); ...


Usamos algo como lo siguiente para conectar programáticamente a nuestros servidores JMX. Debe ejecutar su servidor con algo como los siguientes argumentos:

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

Para enlazar a una dirección particular, deberá agregar los siguientes argumentos de VM:

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

Luego puede conectarse a su servidor usando el código de cliente JMX como se muestra a continuación:

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

También tenemos un código que se puede publicar programáticamente en un puerto particular fuera de los argumentos de la máquina virtual, pero creo que es más de lo que usted necesita.

En términos de conexión "por pid", debes usar Java6 para hacerlo desde Java hasta donde yo sé. No he usado el siguiente código, pero parece que funciona.

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

También soy el autor del paquete SimpleJMX, que hace que sea fácil iniciar un servidor JMX y publicar beans en clientes remotos.

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

También tiene una interfaz de cliente, pero en este momento no tiene ningún mecanismo para encontrar procesos por PID: solo se admiten combinaciones de host / puerto (en 6/2012).


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

Esto requiere que use el argumento jmxremote en el inicio de JVM para el proceso que está tratando de leer. PARA poder hacerlo sin tener que pasar un argumento de jmxremote al inicio. Deberá usar la aplicación adjunta (solo aplicable para Programas que utilicen Java 6 y superior).