Uso de los beans de gestión de la plataforma Java

Mantener las pestañas en su aplicación Java SE 5.0

El último release de la plataforma Java™ incluye una serie de nuevos dispositivos para la supervisión y la gestión de sistemas. En este artículo, tres desarrolladores del IBM Java Technology Centre se asocian para ayudarle a empezar a utilizar esta API. Después de una rápida visión general del paquetejava.lang.management le guiarán a través de una serie de pequeños casos de ejemplos prácticos para probar el rendimiento de una JVM en ejecución.

May Glover Gunn, Software Engineer, IBM, Software Group

May Glover Gunn es un físico de formación, pero se unió a IBM a su antojo hace tres años. Desde entonces, ha trabajado en el Centro de Tecnología Java en los Laboratorios de IBM en Hursley en una variedad de roles. Recientemente, ha desarrollado pruebas para el release de la tecnología Java 5.0 y se encuentra trabajando actualmente en nuevas tecnologías relacionadas con la plataforma Java.



George Harley, Software Developer, IBM, Software Group

George Harley es un desarrollador sénior de los laboratorios de IBM en Hursley que trabaja en el Centro de Tecnología Java. Se ha dedicado por más de una década a la escritura profesional de software en una diversidad de lenguajes. En su tiempo libre trabaja.



Caroline Gough , Software Engineer, IBM, Software Group

Caroline GoughCaroline Gough trabajó como desarrolladora en una pequeña empresa de software durante tres años antes de unirse al equipo de Pruebas de Sistemas del Centro de Tecnología Java en los Laboratorios de IBM en Hursley. Es una probadora sénior, con experiencia en las pruebas de estrés y planificación técnica de RAS (fiabilidad, disponibilidad y servicio). Trabajó en la reciente adaptación de la versión 5.0 de la plataforma Java de IBM y en la actualidad se encuentra preparando pruebas para los futuros releases de la plataforma Java.



16-05-2012

Entre los nuevos dispositivos introducidos en la versión 5.0 de la plataforma Java 2 se encuentran una API que permite a las aplicaciones Java y a las herramientas compatibles supervisar y administrar una Java Virtual Machine (JVM) y el sistema operativo nativo en el que se ejecuta. En este artículo, usted aprenderá sobre las posibilidades de esta nueva plataforma de gestión API, incluida en el paquete java.lang.management . Este artículo le lleva rápidamente a un nuevo conjunto de dispositivos de gran alcance que serán más importante en futuros releases de la plataforma Java.

La supervisión y gestión de una VM 5.0

Java 5.0 proporciona nuevas posibilidades para administrar y ejecutar una máquina virtual. Los desarrolladores y los administradores del sistema pueden supervisar - y, para algunas propiedades, ajustar con precisión - el rendimiento de una VM 5.0. El mecanismo para realizar estas actividades será conocido para cualquiera que tenga experiencia previa en el uso de Java Management Extensions (JMX). A través de la tecnología JMX, un conjunto de recursos de la plataforma a controlar pueden ser considerados como simples objetos bien definidos, cuyas propiedades se correlacionan con las características de bajo nivel de los recursos dados.

En la API de administración de la plataforma, estos objetos bien definidos se llaman MXBeans. Si usted piensa que un MXBean suena como un tipo del posiblemente más conocido MBean, entonces está en lo correcto. Estos MXBeans (o plataforma MBeans) son, en efecto, beans de gestión que encapsulan partes específicas del funcionamiento interno de la plataforma 5.0. La Figura 1 ilustra cómo los MXBeans encajan en la imagen más grande:

Figura 1. los MXBeans proporcionan interfaces de gestión para la plataforma Java
los MXBeans proporcionan interfaces de gestión para la plataforma Java

Usted puede descubrir y personalizar diferentes clases de funcionalidad en la ejecución de una VM 5.0 compatible, por ejemplo, puede obtener los detalles sobre el comportamiento del sistema de compilación just-in-time que puede estar en uso u obtener cifras del progreso del servicio de recogida de basura.

Cualquier aplicación Java puede hacer uso de los beans de la plataforma, simplemente obteniendo la referencia bean necesaria, (utilizando las técnicas que analizaremos en este artículo) y a continuación invocando la llamada del método apropiado. En el caso más simple, el cliente de bean puede descubrir información sobre la plataforma que el propio cliente está ejecutando. Pero un cliente también puede controlar el comportamiento de una completamente separada JVM. Esto es posible porque un MXBean es una clase de MBean y se puede gestionar de forma remota utilizando los servicios estándar JMX disponibles en Java 5.0.


JConsole

Un ejemplo de un cliente bean es la herramienta JConsole que se suministra con Java SE 5.0 SDK. Esta es una interfaz gráfica que se conecta a una JVM para mostrar información sobre la misma. Las pestañas en la GUI se relacionan a aspectos particulares de la JVM, existen pestañas de memoria, hebras y clases. La herramienta JConsole también proporciona una pestaña de resumen general, una pestaña VM que proporciona información sobre el entorno en el que se inició la VM, y una pestaña MBeans con la que el usuario puede inspeccionar el estado de la plataforma MBeans con más detalle.

Al ejecutar JConsole,

se puede iniciar JConsole simplemente escribiendo jconsole. en un prompt de comando, asumiendo que el directorio bin del SDK está en su vía de acceso. Introduzca el nombre de host donde la JVM que desea supervisar se está ejecutando junto con el número de puerto en el cual se escuchan las solicitudes de gestión -- junto con los detalles de autenticación necesarios -- y entonces haga clic en Connect. Al hacer clic enConnect con los valores predeterminados dellocalhost y port 0 , se supervisa la JVM que está siendo utilizada para ejecutar la propia JConsole (ya que JConsole es un proceso Java). Esto se conoce como modalidad de auto-control. La Figura 2 ilustra el inicio de JConsole:

Figura 2. Inicio de JConsole
Inicio de JConsole

JConsole en acción

Una vez se ha establecido una conexión a una JVM, JConsole se inicia mediante la pestaña Resumen, como se muestra en la Figura 3:

Figura 3. Pestaña Resumen de JConsole
Pestaña Resumen de JConsole

Desde aquí, usted puede seleccionar cualquiera otra pestaña. Por ejemplo, la pestaña Memoria, que se ilustra en la Figura 4, muestra un historial del uso de cada agrupación de memoria en la JVM:

Figura 4. Pestaña Memoria de JConsole
Pestaña Memoria de JConsole

Observe el botón Perform GC en la esquina superior derecha del panel. Este es un ejemplo de una de las muchas operaciones que se pueden invocar en la JVM utilizando la plataforma MBeans.


¿Cómo funciona?

Apoyando todo lo que ha leído hasta ahora está el concepto de un bean gestionado, o MBean. Se puede pensar en los MBeans como la representación programática de la interfaz de gestión de un recurso. En términos más sencillos, se puede pensar en ellos como derivadores de Java alrededor de una entidad a controlar. En términos más prácticos aún, los MBeans son las clases de Java, cuyos métodos públicos son escrito de acuerdo a un conjunto de reglas bien definidas, estas reglas hacen cumplir la encapsulación completa de las características de una aplicación o un recurso a administrar. En última instancia, el gestor del recurso (donde quiera que esté y donde quiera que habite en la red) localiza y utiliza el MBean correspondiente para fines de control.

A través de su API, un MBean proporciona información sobre lo siguiente, todos lo que se ilustra en la figura 5:

  • El estado actual del recurso, a través de sus propiedades de
  • Operations que pueden invocarse a través de las notificaciones de evento
  • posibles a los agentes de gestión que pueden ser enviadas a las partes interesada.
Figura 5. Los clientes MBean hacen uso de las propiedades, operaciones, y eventos.
Los clientes MBean hacen uso de las propiedades, operaciones, y eventos.

Una vez que se crea, tiene que registrar un MBean con un servidor MBean. Además de jugar el rol de un registro de MBean, el servidor MBean también proporciona una manera de que los sistemas de gestión encuentren y utilicen los MBeans registrados. La funcionalidad adicional para la gestión de MBeans registrados es llevada a cabo por los servicios de agente JMX . Tales servicios incluyen la supervisión de los valores de los atributos de un MBean y la notificación a las partes interesadas sobre los cambios que se realizan, la notificación a los receptores periódicamente con información específica sobre un MBean, y la vigilancia de las relaciones entre MBeans. Los servicios de agente JMX son a menudo los propios MBeans.

La combinación de un servidor de MBean con los servicios de agente JMX obligatorios se conoce como un agente JMX, el cual se muestra en la Figura 6:

Figura 6. El agente JMX.
El agente JMX.

Un agente JMX puede hacer que se gestionen sus recursos - es decir, el conjunto de MBeans actualmente registrados en su servidor MBean --- disponible para otros agentes remotos.

Antes que el release Java 5.0, la API javax.management era una extensión opcional de la plataforma Java que los usuarios podían obtener en una descarga por separado y poner en marcha como medio de gestión y supervisión de los recursos a través de código Java. Los Recursos en este contexto, pueden significar aplicaciones, servidores J2EE que ejecutan aplicaciones críticas de empresa, objetos Plain Old Java (POJO), e incluso entidades de hardware, como dispositivos de red, descodificadores, equipos de telecomunicaciones, o similares.Si se puede hacer referencia a partir del código Java, entonces puede convertirse potencialmente en un recurso administrado.

A pesar de que en realidad aquí sólo hemos arañado la superficie de JMX, hemos cubierto lo suficiente para permitirnos echar un vistazo a los MXBeans. Un completo análisis del diseño y las posibilidades de JMX está fuera del alcance de este artículo. Para una excelente visión general de la parte que juega JMX en las aplicaciones de gestión de red, se pueden leer las series de Sing Li sobre el tema (ver Recursos).


¿Qué son los MXBeans y cómo puedo utilizarlos?

Así que ahora que sabe lo que son los MBeans, echemos un vistazo a sus homónimos cercanos como se define en el paquete java.lang.management , MXBeans. La buena noticia es que los MXBeans no se apartan de los conceptos que introducimos cuando los analizamos. La mayoría de tipos en este paquete son interfaces que siguen un convenio de denominación similar los que se utilizan para los MBeans estándar: el nombre del recurso de la plataforma que se instrumenta seguida por el sufijo MXBean. (Para los MBeans estándar el sufijo MBean se esperará, por supuesto.)

La Tabla 1 describe los recursos de la plataforma que están disponibles para la instrumentación a través de las interfaces MXBean proporcionadas en el paquete java.lang.management :

Tabla 1. Recursos de la plataforma que se pueden administrar a través de MXBeans
Recurso de la plataformaCorrespondiente a MXBeanNúmero disponible
CompilaciónCompilationMXBean0 o 1
Sistema de recogida de basurasGarbageCollectorMXBeanAl menos 1
MemoriaMemoryMXBeanExactamente 1
Gestores de memoriaMemoryManagerMXBeanAl menos 1
EnhebradoThreadMXBeanExactamente 1
Sistema operativo OperatingSystemMXBeanExactamente 1
Sistemas de tiempo de ejecución RuntimeMXBeanExactamente 1
Sistema de carga de clase ClassLoadingMXBeanExactamente 1
Recursos de memoriaMemoryPoolMXBeanAl menos 1

Para cada MXBean, la interfaz que los clientes deben programar está firmemente establecida en la especificación de Java 5.0. En la actualidad no hay manera de que los usuarios pueden personalizar una interfaz como la que se expone en los atributos más manejables de la plataforma.

El número de posibles instancias de cada tipo de MXBean, se indica en la tercera columna de la Tabla 1, depende en gran medida el sistema de plataforma en particular que se administra. Por ejemplo, como la especificación JVM permite a los implementadores elegir los algoritmos de recogida de basura utilizados, es totalmente razonable para cualquier número de recopiladores de basura - y por lo tanto, cualquier número de instancias de GarbageCollectionMXBean -- que se activen simultáneamente. Contrasta con el OperatingSystemMXBean, del cual sólo puede haber una instancia disponible, como la máquina virtual instrumentada, obviamente sólo se puede ejecutar en un sistema operativo en un momento dado.

El código de cliente puede asumir con seguridad que los excepcionales MXBeans son verdaderamente únicos en la VM. Cada vez que se solicita una referencia a estos excepcionales tipos, siempre se responde con la misma instancia, independientemente de donde se hace la solicitud y cuando se produce en el ciclo de vida de la VM. Esto es cierto incluso cuando varios clientes están controlando una VM en particular.

El MBeanServerConnection

La interfaz javax.management.MBeanServerConnection es un supertipo de la interfaz javax.management.MBeanServer que se pueden utilizar para llamar al servidor de MBean si se está ejecutando en la misma VM que el código de cliente (es decir, si el cliente de administración y el agente JMX son co-ubicados en la misma VM). Debido a que existe una relación padre-hijo entre MBeanServerConnection y MBeanServer, los clientes pueden utilizar el mismo método llamado a interactuar con los servidores MBean locales o remotos.

Para un código de cliente Java, una instancia MXBean se comporta como cualquier POJO. La información se puede adquirir a través de una llamada directa al objeto sin la necesidad de ningún otro participante. Por supuesto, esto sólo es el caso siempre y cuando el cliente Java haya obtenido una referencia a un bean local (que se ejecuta en la misma VM como en la aplicación de gestión) directamente o bien haya solicitado un proxy a un componente de encapsulación de un bean de una VM remota. En ambos casos, la referencia se obtiene de la única plataforma ManagementFactory..

Además de puede acceder a un bean de la plataforma a través de javax.management.MBeanServerConnection, pero en tal caso, hay un nivel extra de indirección en la conversación. Como puede ver en Supervisión de una VM remota a través del servidor de la plataforma, en ese caso de ejemplo los clientes siempre realizan una solicitud a MBeanServerConnection para localizar y realizar llamadas en su nombre a los beans remotos especificados. Esto está en consonancia con el análisis de JMX proporcionado con anterioridad, en el que se observa que para emitir llamadas en cualquier MBean remoto, los clientes remotos debe comunicarse con el servidor MBean en el que está registrado el MBean.

los MXBeans no son JavaBeans.

Para evitar cualquier confusión, usted debe recordar que si bien es perfectamente correcto pensar en un MXBean como una especie de MBean que ayuda a supervisar y controlar una JVM, sin duda, no es correcto pensar en un MXBean como un tipo de JavaBean. La tecnología JavaBeans es el modelo de componentes para la plataforma Java que fue diseñado para ofrecer la capacidad de construir aplicaciones a partir de componentes reutilizables Java utilizando herramientas gráficas. Mientras que algunos de los dispositivos de JavaBeans, como los importantes convenios de denominación para ayudar a descubrir las propiedades a través de las herramientas, están presentes en el espacio de MBean y MXBean, hay una gran diferencia entre las dos tecnologías. No las confunda.

El extra MXBean.

Al comienzo de este artículo, mencionamos que el paquete java.lang.management aloja la API de gestión de la plataforma.Bien, aquí tenemos que corregir esa sentencia ligeramente porque no todos los MXBeans están en realidad contenidos en ese paquete. Debido a que el LoggingMXBean está tan intrínsecamente ligado a la funcionalidad de registro cronológico de la plataforma Java, tenía más sentido alojarlo en el paquete java.util.logging . Como era de esperar de su nombre, este tipo de MXBean proporciona una interfaz de gestión para ejecutar un recurso de registro cronológico de la VM. A partir de una referencia a este bean, los clientes pueden obtener los nombres de todos los registradores que han sido grabados en la plataforma y sus relaciones con los demás. También está disponible la posibilidad de obtener y establecer el nivel de un registrador de la plataforma denominada.

Como el OperatingSystemMXBean y el ThreadMXBean (por mencionar otros dos ejemplos), el LoggingMXBean existe como único en la VM que se está ejecutando. Cualquier obtención o establecimiento en las propiedades expuestas, a través de cualquier medio de comunicación, son siempre enviadas a la misma instancia del objeto.


Obtener MXBeans.

Existen tres formas para que el código del cliente acceda a los MXBeans: a través de los métodos de fábrica, a través del servidor de la plataforma, o como proxies.

Métodos de fábrica.

La forma más sencilla de recuperar los MXBeans es utilizar los métodos estáticos proporcionados en la clase java.lang.management.ManagementFactory . Sin embargo, los MXBeans obtenidos de esta manera sólo se puede utilizar para supervisar su VM local. La claseManagementFactory define un método de recuperación de MXBean. Algunos de estos métodos devuelven una sola instancia del MXBean, y otros devuelven una lista más estricta de las instancias de MXBean.

Cuando sólo hay un MXBean de un tipo específico, el código para recuperarlo es simple. El Listado 1 muestra el código para recuperar el ThreadMXBean.:

Listado 1. Recuperar una referencia del ThreadMXBean único de la plataforma
ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();

Para aquellos tipos de MXBean donde puedan existir varias instancias del MXBean, hay métodos de fábrica que devuelven el MXBeans en una Lista, como se muestra en el Listado 2:

Listado 2. Recuperación de una lista más estricta de todos MemoryPoolMXBeans conocidos en la plataforma
List<MemoryPoolMXBean> memPoolBeans = ManagementFactory.getMemoryPoolMXBeans();
for (MemoryPoolMXBean mpb : memPoolBeans) {
    System.out.println("Memory Pool: " + mpb.getName());
}

El LoggingMXBean es un componente del paquete java.util.logging y como resultado, se accede a él mediante la claseLogManager, en lugar de la clase ManagementFactory , como aparece en el Listado 3:

Listado 3. Obtención de la referencia LoggingMXBean desde el LogManager
LoggingMXBean logBean = LogManager.getLoggingMXBean();

Recuerde, estos métodos sólo le permiten acceder a los MXBeans que pertenecen a su VM local . Si desea ampliar el alcance de su código de cliente a distancia para instrumentar las JVM remotas ubicadas en la misma máquina o en los diferentes nodos en total, entonces tiene que utilizar uno de los dos métodos que se describen a continuación.

A través del servidor de la plataforma.

Estructurar el código para realizar llamadas en una conexión a un servidor MBean de VM remoto es, una opción disponible para usted. Para que esto tenga éxito, primero tendrá que lanzar la VM remota con clave de opciones de línea de comandos. Estas establecen el puerto en el que su agente JMX asociado escucha las solicitudes y el nivel de seguridad que estará en vigor. Por ejemplo, las siguientes opciones inician una VM, cuyo agente escucha en el puerto 1234 sin seguridad:

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

El permitir un acceso seguro a una VM se cubre posteriormente en este artículo en la sección de Seguridad .

Con el agente remoto escuchando, se puede usar el fragmento de código en el Listado 4 para obtener una referencia de la conexión del servidor MBean asociada:

Listado 4. Uso de JMXConnectorFactory para conectar a un servidor MBean de una VM diferente
pruebe {
    // connect to a separate VM's MBeanServer, using the JMX RMI functionality
    JMXServiceURL address =
      new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:1234/jmxrmi");
    JMXConnector connector = JMXConnectorFactory.connect(address);
    MBeanServerConnection mbs = connector.getMBeanServerConnection();
} catch ...

Una vez que ha recuperado el MBeanServerConnection, usted puede utilizar los métodos JMX getAttribute(), setAttribute() y invoke() para trabajar con los MXBeans. Esto se cubre en Supervisión de una VM remota a través del servidor de la plataforma..

Como proxies.

El tercer enfoque para acceder a las API beans de la plataforma comparte algunas similitudes con los dos métodos ya introducidos. Al igual que antes, usted tiene que recuperar MBeanServerConnection del agente JMX de la VM de desea supervisar. A continuación, utilizando el método ayudante estático en la clase ManagementFactory , el código del cliente puede solicitar una instancia de proxy a un MXBean denominado registrado en el servidor MBean de la VM remota. El Listado 5 ilustra un ejemplo:

Listado 5. Una referencia a un servidor MBean remoto puede obtener proxies para un MXBeans remoto.
pruebe {
    ThreadMXBean threadBean = ManagementFactory.newPlatformMXBeanProxy
        (mbs, ManagementFactory.THREAD_MXBEAN_NAME, ThreadMXBean.class);
} catch ...

Para todos los MXBeans únicos excepto el LoggingMXBean, los nombres de cadena de caracteres completa que se utilizan para el registro de servidor están disponibles en los campos estáticos públicos de la clase ManagementFactory . Así por ejemplo, la representación de la cadena de caracteres del javax.management.ObjectName deThreadMXBean se almacena en el campo THREAD_MXBEAN_NAME . De igual manera, el nombre de registro de LoggingMXBean se almacena en un campo estático en la clase java.util.logging.LogManager . El Listado 6 demuestra una solicitud de una instancia proxy para LoggingMXBean:

Listado 6. El nombre de la cadena de caracteres de LoggingMXBean es una constante de la clase java.util.logging.LogManager
pruebe {
    LoggingMXBean logBean = ManagementFactory.newPlatformMXBeanProxy
        (mbs, LogManager.LOGGING_MXBEAN_NAME, LoggingMXBean.class);
} catch ...

Con los tipos de MXBean donde más una instancia puede existir en la VM, las cosas se vuelven un poco más participativas. En tales casos, primero debe utilizar el MBeanServerConnection para obtener los nombres de todos los MXBeans registrados de un determinado tipo. Por comodidad, el componente de dominio de ObjectName para cada MXBean no único se almacena en los campos estáticos públicos en ManagementFactory.. Una vez que se recuperan los nombres, se pueden utilizar uno por uno para la construcción de una instancia proxy por separado. El Listado 7 muestra un ejemplo:

Listado 7. Creación de proxies para cada MemoryManagerMXBean que pertenecen a una VM remota
try {
        // Get the names of all the Memory Manager MXBeans in the server
        Set srvMemMgrNames = mbs.queryNames(new ObjectName(
            ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE + ",*"), null);
        
        // Get a MXBean Proxy for each name returned
        for (Object memMgrName : srvMemMgrNames){
            // Cast Object to an ObjectName
            ObjectName memMgr = (ObjectName) memMgrName;
            
            // Call newPlatformMXBeanProxy with the complete object name
            // for the specific MXBean
            MemoryManagerMXBean memMgrBean = 
                ManagementFactory.newPlatformMXBeanProxy(
                    mbs, memMgr.toString(), MemoryManagerMXBean.class);
                    
            // memMgrBean is a proxy to the remote MXBean. We can use it 
            // just as if it was a reference to a local MXBean.
            System.out.println("Memory Manager Name = " +
                memMgrBean.getName());
        }
} catch ...

Uso de MXBeans.

Las operaciones definidas a través de cada intefaz de MXBean se indican en la documentación java.lang.management . A través de estas operaciones, el usuario puede gestionar y supervisar la máquina virtual. Por ejemplo, en MemoryMXBean, existen operaciones que le permiten activar una salida detallada de la memoria del sistema, solicitar la recogida de basura, y recuperar información detallada sobre el uso de la memoria actual por las agrupaciones de memoria con y sin almacenamiento dinámico. Por lo tanto, si estaba preocupado por la cantidad de memoria que estaba utilizando una aplicación Java o desea ajustar el tamaño del almacenamiento dinámico, podría escribir fácilmente un cliente de administración utilizando la API java.lang.management para conectar con la aplicación y controlar el uso de la memoria.

De igual manera, ThreadMXBean ofrece una funcionalidad que podría ser útil si la aplicación Java se cuelga. El método findMonitorDeadlockedThreads() devuelve los ID de cualquier hebra que se identifica como un punto muerto. Entonces, se pueden utilizar estos ID para recuperar información detallada sobre las hebras, incluyendo el rastreo de pila, sus estados, si estaban ejecutando un código nativo, y así sucesivamente.

Esta información de hebra se suministra en una instancia de ThreadInfo , una de las tres clases en el paquete java.lang management utilizado por MXBeans para devolver instantáneas de los datos a un usuario -- las otras son las clases MemoryUsage y MemoryNotificationInfo . Cada una de estos es un tipo de datos complejos que contiene información estructurada que describe las cualidades específicas de la plataforma.

Ahora echemos un vistazo a dos casos de ejemplo que ilustran cómo las ideas que se comentan anteriormente se traducen en el código Java.


Ejemplo 1: Control de una VM a través de MXBeans o proxies.

Como hemos comentado, los métodos de un MXBean se pueden llamar directamente desde un MXBean local o bien a través de un proxy. El Listado 8 muestra cómo utilizar las operaciones método getter y método setterThreadMXBean. La variable threadBean en este ejemplo puede ser un MXBean recuperado de la VM local o un proxy para el MXBean desde una VM remota. Es transparente al interlocutor una vez que se ha adquirido la referencia.

Listado 8. Obtener y establecer los valores de un ThreadMXBean
try {
    // Get the current thread count for the JVM
    int threadCount = threadBean.getThreadCount(); 
    System.out.println(" Thread Count = " + threadCount);
       
    // enable the thread CPU time
    threadBean.setThreadCpuTimeEnabled(true);
} catch ...

El método setThreadCpuTimeEnabled(), que se utiliza en el Listado 8 es opcionalmente soportado por las VM5.0 compatible. La verificación requerida cuando se utiliza tal funcionalidad opcional se muestra en el Listado 9:

Listado 9. Verificación de que esa propiedad opcional es compatible antes que intentar utilizarla
si (threadBean.isThreadCpuTimeSupported()) {
    threadBean.setThreadCpuTimeEnabled(true);
}

El método getTotalCompilationTime() del tipo CompilationMXBean, también contiene una funcionalidad que no estará disponible necesariamente en todas las implementaciones de VM 5.0-compatible. Como con setThreadCpuTimeEnabled(), en el listado 9, hay un método asociado disponible para comprobar si existe soporte. El código que no se aprovecha de estos métodos de verificación tiene que manejar cualquier java.lang.UnsupportedOperationException que pueda ser lanzada a través de métodos opcionales.

El Listado 10 demuestra cómo acceder a información sobre todas las hebras que se ejecutan en la VM. Cada información de hebra se almacena en un objeto ThreadInfo separado dedicado, el cual se puede consultar posteriormente.

Listado 10. Obtención de los nombres de todas las hebras que se ejecutan en una VM
try {
    // Get the ids of all the existing threads
    long[] threadIDs = threadBean.getAllThreadIds();
    
    // Get the ThreadInfo object for each threadID
    ThreadInfo[] threadDataset = threadBean.getThreadInfo(threadIDs);
    for (ThreadInfo threadData : threadDataset) {
        if (threadData != null) {
            System.out.println(threadData.getThreadName());
        }
    }
} catch ...

Tenga en cuenta que la información contenida en los tipos complejos como ThreadInfo, MemoryUsage y MemoryNotificationInfo es meramente una instantánea del sistema en el momento en que se realizó la llamada de adquisición. Estos objetos no se actualizan dinámicamente después de que usted obtenga una referencia de ellos, así que, si la aplicación necesita datos frescos en uno de estos aspectos de la VM administrada, es necesario realizar otra llamada para obtener un ThreadInfo actualizado u objeto MemoryUsage . Los objetos MemoryNotificationInfo son un poco diferentes en este respecto, ya que no son extraídos por las aplicaciones de gestión, sino que más bien son empujados a los eventos de notificación (que analizaremos en más detalle próximamente).


Ejemplo 2: Supervisión de una VM remota a través de la plataforma del servidor.

El acceso al ThreadMXBean de una JVM remota por medio de un MBeanServerConnection no es tan sencillo como el ejemplo que aparece en el Listado 1. En primer lugar, usted necesitará una instancia javax.management.ObjectName para el ThreadMXBean.. Esto se puede crear con la misma cadena de caracteres de nombres que un objeto proxy MXBean, como se muestra en el Listado 11:

Listado 11. Construcción de un ObjectName para un ThreadMXBean
try {
    ObjectName srvThrdName = new ObjectName(ManagementFactory.THREAD_MXBEAN_NAME);
    ...
} catch ...

Se puede utilizar la instancia ObjectName para identificar el ThreadMXBean específico remoto en posteriores llamadas a los métodos getAttribute(), setAttribute() y invoke() del MBeanServerConnection, como aparece en el Listado 12:

Listado 12. Poner el ObjectName en buen uso en las llamadas al servidor MBean remoto
try {
    // Get the current thread count for the JVM
    int threadCount = 
      ((Integer)mbs.getAttribute( srvThrdName, "ThreadCount")).intValue();
    System.out.println(" Thread Count = " + threadCount);
    
    boolean supported = 
      ((Boolean)mbs.getAttribute(srvThrdName, "ThreadCpuTimeSupported")).booleanValue();
    if (supported) { 
        mbs.setAttribute(srvThrdName, 
          new Attribute("ThreadCpuTimeEnabled", Boolean.TRUE)); 
        ...    
    }
} catch ...

El Listado 13 demuestra cómo acceder a la información sobre todas la hebras actuales en la VM a través de la conexión al servidor de MBean. MXBeans accede utilizando este enfoque a los tipos de datos complejos de devolución, recortando el tipo complejo dentro de un tipo abierto de JMX, como un objeto javax.management.openmbean.CompositeData .

¿Por qué están los datos complejos recortados dentro de un tipo intermedio? Tenga en cuenta que MXBeans podrían ser potencialmente administrados por las aplicaciones remotas que no estén realmente escritas en lenguaje Java o por aplicaciones Java sin acceso a todos los tipos complejos utilizados para describir diversas cualidades de los recursos gestionados. Si bien es seguro asumir que ambos extremos de la conexión al agente JMX de la plataforma, comprenderá los tipos sencillos, como boolean, long, y string , y los correlacionará a los tipos correspondientes en su lenguaje de implementación respectivo, no es realista asumir que los tipos complejos, tales como ThreadInfo o MemoryUsage serán interpretados correctamente por cada aplicación de gestión posible.Tipos abiertos comoCompositeData pueden representar datos complejos (es decir, no primitivos o estructurado) en cuanto a los tipos más fundamentales.

Si usted realiza una llamada remota a un MXBean 5.0 que requiere pasar una instancia de un tipo complejo, el objeto se convierte en el equivalente de CompositeData . Mientras esto activa el envío de información a la gama más amplia de clientes posible, hay un inconveniente: La recepción de aplicaciones Java que realmente pueden resolver los tiposThreadInfo yMemoryUsage seguirán no obstante necesitando convertirse del tipo abierto al tipo complejo por ellos mismos. Pero incluso eso no es demasiado oneroso a un paso, como todos los tipos de datos complejos de soporte definidos en java.lang.management tienen sus propios métodos de conveniencia estática para hacer esto.

En el Listado 13, el atributo threadDataset contiene una matriz de objetosCompositeData que se correlacionan directamente a los objetos ThreadInfo . Para cada hebra, el método estático de ThreadInfofrom() se utiliza entonces para la construcción de un objeto ThreadInfo equivalente del CompositeData.. Se puede utilizar este objeto para acceder a la información de cada hebra.

Listado 13. El tipo CompositeData transfiere complejas estructuras de datos por la red
try {
    // Get the ids of all the existing threads
    long[] threadIDs = (long[])mbs.getAttribute(srvThrdName, "AllThreadIds");
    
    // Get the ThreadInfo object for each threadID. To do this we need to 
    // invoke the getThreadInfo method on the remote thread bean. To do 
    // that we need to pass the name of the method to run together with the 
    // argument and the argument type. It's pretty ugly we know.  
    CompositeData[] threadDataset = 
      (CompositeData[]) (mbs.invoke(srvThrdName, "getThreadInfo",
        new Object[]{threadIDs}, new String[] {"[J"}));
         
    // Recover the ThreadInfo object from each received CompositeData using
    // the static helper from() method and then use it to print out the
    // thread name.     
    for (CompositeData threadCD : threadDataset) {
        ThreadInfo threadData = ThreadInfo.from(threadCD);
        if (threadData != null) {
            System.out.println(threadData.getThreadName());
        }
    }
} catch ...

Soporte de API.

Si usted desarrolla un código de gestión de la plataforma que verifica el estado de las hebras VM, entonces puede que encuentre interesantes algunos comportamientos con los que nos topamos por casualidad mientras realizábamos este artículo.¿Afectará a su código? Eso depende de en qué medida la aplicación utiliza la versión 5.0 del nuevo mecanismo de la plataforma Java para proteger los bloques de código a un acceso simultaneo.

El nuevo paquete 5.0 java.util.concurrent.locks introduce la claseReentrantLock que, como su nombre sugiere, se puede utilizar para construir un bloqueo de reentrada para proteger secciones críticas de código. Es muy parecido al mecanismo de bloqueo implícito establecido que usted obtiene con la palabra clave sincronizada, pero tiene algunas posibilidades adicionales que pueden ser útiles para un control más refinado del bloqueo explícito. El Listado 14 muestra un ejemplo de su utilización:

Listado 14. Un uso muy simple de ReentrantLock
private Lock myLock = new ReentrantLock();

...

void myMethod() {
    // Acquire the lock
    myLock.lock();
    try {
        ... do work in critical section ...
    } finally {
        // Relinquish the lock
        myLock.unlock();
    }// end finally

...

}

Antes de entrar en la sección critica, se invoca el método lock() del objeto ReentrantLock para intentar y obtener el bloqueo. Esto sólo da resultado si otra hebra ya no tiene el bloqueo, en cuyo caso la hebra actual está bloqueada. Antes de la versión 5.0 de la plataforma Java, usted podría haber escrito la funcionalidad en el Listado 14 en código con algo así en el Listado 15. (usted todavía puede, por supuesto, como sincronizada no ha desaparecido.)

Listado 15. Un método sincronizado
synchronized void myMethod() {

... realizar un trabajo en un sección crítica ...

}

En estos usos sencillos, no se apreciará una diferencia en el comportamiento del código. Si, sin embargo, usted hace uso de los tipos ThreadMXBean y ThreadInfo para verificar el recuento bloqueado de una hebra que se conoce que se bloqueará la entrada a una sección crítica en el curso de un programa en ejecución, el resultado será diferente dependiendo del método de bloqueo que se utiliza. usted mismo puede demostrar esto escribiendo algún código simple que tenga dos hebras diferentes intentando realizar una llamada a myMethod(), y forzar a una hebra a llegar siempre allí en segundo lugar.Esa hebra, obviamente será bloqueada y deberá tener una cuenta bloqueada de exactamente uno. Utilizando la palabra clave sincronizada con myMethod() usted verá, como era de esperar, una cuenta bloqueada mayor que cero del objeto ThreadInfo asociado a la hebra. Sin embargo, utilizando el nuevo enfoque ReentrantLock , podrá verá una cuenta bloqueada de cero. Es una apuesta segura que, como la posibilidad de supervisión de la VM ThreadMXBean alcanza el mismo nivel con los paquetes nuevos simultáneos, esta diferencia en el comportamiento observado se eliminará en futuros releases de la plataforma Java.


Notificaciones.

ElMemoryMXBean es único entre los MXBeans en que tiene la posibilidad de enviar notificaciones dinámicas de los eventos interesantes sobre el uso de la memoria de los objetos de los clientes. Los beneficios de la comunicación inmediata en asuntos tales como el uso de memoria que supera un umbral preestablecido deberían ser obvia, ya que puede ser un síntoma de problemas a nivel de aplicación, o bien indicar que la máquina virtual necesita otro ajuste.

El modelo de notificación que utiliza MemoryMXBean proviene de la especificación JMX MBean, que a su vez es muy parecida al modelo de notificación de eventos que se utiliza en la programación Java. Como un emisor de notificaciones, el MemoryMXBean implementa la interfaz JMX javax.management.NotificationBroadcaster, una interfaz relativamente pequeña que permite al bean tanto registrar como dar de baja a las partes interesadas. Por otra parte, cada una de las partes interesadas (objeto) debe implementar la interfaz javax.management.NotificationListener . Esta interfaz consiste en una sola operación, la cual es invocada por el evento de emisión de un MXBean cuando se produce un evento.

Los receptores se pueden registrar (o dar de baja) con el MemoryMXBean en cualquier momento durante el ciclo de vida de la VM. Las notificaciones sólo se emiten al conjunto actual de registrados.

Cuando se realiza una llamada a un método manejador del receptor, recibe una instancia de la clase javax.management.Notification . Este es el tipo de señal de evento genérico en el modelo de notificación de eventos de JMX. Su diseño es tal que se puede establecer para mantener una cantidad considerable de información sobre el evento que llevo a su creación. Para el MemoryMXBean, existen en la actualidad dos tipos de notificaciones:

  • Un recurso de memoria (a veces llamado agrupación de memoria) en la VM ha crecido hasta superar un valor previamente establecido. Esta clase de evento es identificado por la constante MemoryNotificationInfo MEMORY_THRESHOLD_EXCEEDED ..
  • El tamaño del recurso de memoria de inmediato después de la recogida de memoria es mayor que un valor de umbral previamente establecido. Esto es identificado por la constante MemoryNotificationInfo MEMORY_COLLECTION_THRESHOLD_EXCEEDED ..

A la recepción del objeto Notificación en el método manejador, un receptor registrado puede determinar el tipo de evento que se ha producido mediante la consulta del tipo de Notificación, y comprobar la cadena de caracteres en contra de los dos valores MemoryNotificationInfo .

Para transferir información detallada sobre el evento a los receptores, el MemoryMXBean establece cada propiedad de los datos de usuario del objeto de Notificación esencialmente, (un medio para que la emisora incluya todo lo que quiera) con una instancia concreta de javax.management.openmbean.CompositeData que representa un objeto MemoryNotificationInfo . Tal y como explicamos en Supervisión de una VM remota a través del servidor de la plataforma, la encapsulación de los datos del evento dentro de un tipo abierto de JMX permite que lo entienda el conjunto más amplio de receptores.


Seguridad

Hasta el momento, vamos bien. Ahora es el momento para hacer frente a algo que no se puede pasar por alto: la seguridad. ¿Qué ocurre si usted no quiere que el código de aplicación de una persona pueda acceder y modificar la VM? ¿Qué opciones están disponibles? Existen algunas propiedades del sistema que se pueden configurar para controlar el nivel de acceso y la forma en que los datos de la VM se transmiten desde el agente JMX hasta el cliente de administración. Estos recaen en dos categorías: la autenticación de la contraseña y la Secure Sockets Layer (SSL).

por medio de las opciones de línea de comandos.

Para hacer accesible a una VM 5.0-compatible a la supervisión y gestión, es necesario instalar un número de puerto para el agente JMX de la plataforma por medio de la siguiente opción de línea de comandos:

-Dcom.sun.management.jmxremote.port=<number>

En el caso poco probable de que no le importe quién pueda acceder a su VM a través de este puerto, también se puede desactivar la autenticación de la contraseña y el cifrado SSL (las cuales están habilitadas de manera predeterminada) añadiendo las dos opciones siguientes:

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

El uso de estas tres opciones a la vez es conveniente cuando se encuentra desarrollando el código de cliente java.lang.management y desea ser capaz de supervisar otra VM fácilmente. En un ambiente de producción, es necesario instalar el control de contraseña o el SSL (y posiblemente los dos).

Autenticación de la contraseña

En el directoriojre/lib/management del 5.0 SDK, encontrará un archivo llamado jmxremote.password.template. Esto define nombres de usuario y contraseñas para dos roles. El primero es un rol de supervisión , permitiendo el acceso a funciones de gestión de sólo lectura; el segundo rol es un rol de control para funciones de escritura y lectura. Los clientes pueden autenticar los nombres de usuario monitorRole o controlRole , dependiendo del nivel de acceso necesario. Para garantizar que sólo estos usuarios autenticados puedan tener acceso, necesita hacer lo siguiente:

  1. Copiar el contenido de jmxremote.password.template en un archivo llamado jmxremote.password y eliminar los comentarios de las líneas al final del archivo que definen los nombres de usuario y las contraseñas, cambiando las contraseñas a su gusto.
  2. Modificar los permisos en jmxremote.password de modo que sólo los pueda leer y modificar el propietario. (En los sistemas UNIX y UNIX-like, establecer los permisos a 600. En Microsoft Windows, siga las instrucciones en el artículo "Cómo proteger un archivo de contraseña en los sistemas de Microsoft Windows", del cual se puede encontrar un enlace en Recursos.)
  3. Al iniciar la VM, especifique la ubicación del archivo de contraseñas para utilizarlo con la siguiente opción de línea de comandos:

    -Dcom.sun.management.jmxremote.password.file=<file-path>

Desde la perspectiva del cliente de gestión, es necesario proporcionar una combinación válida de nombre de usuario/contraseña para acceder a una VM que tenga activada la autenticación. Si el cliente es JConsole, esto es fácil: los campos de nombre de usuario y contraseña se proporcionan en la pestaña de conexión inicial. Para escribir el código que proporciona los detalles de autenticación para una VM remota, es necesario añadir las modificaciones que se muestran en el Listado 16 del código de conexión previamente dado en el Listado 4:

Listado 16. Conexión a una VM remota que requiere la autenticación del usuario
try {
    // provide a valid username and password (e.g., via program arguments)
    String user = "monitorRole";
    String pw = "password";
    
    // place the username and password in a string array of credentials that
    // can be used when making the connection to the remote JMX agent
    String[] credentials = new String[] { user, pw };

    // the string array of credentials is placed in a map keyed against the 
    // well-defined credentials identifier string    
    Map<String, String[]> props = new HashMap<String, String[]>();
    props.put("jmx.remote.credentials", credentials);

    // supply the map of credentials to the connect call
    JMXServiceURL address = 
      new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1234/jmxrmi");
    JMXConnector connector = JMXConnectorFactory.connect(address, props);
    
    // it is a trivial matter to get a reference for the MBean server
    // connection to the remote agent 
    MBeanServerConnection mbs = connector.getMBeanServerConnection();
} catch ...

El proporcionar un nombre de usuario o contraseña no válido a una VM que requiera autenticación, da lugar a un java.lang.SecurityException.. De igual forma, el autenticar como el monitorRole y a continuación tratar de invocar una de las operaciones de lectura y escritura -- como intentar solicitar la recogida de basura -- también provoca el lanzamiento de un SecurityException .

Uso de SSL.

Se puede utilizar el SSL para cifrar la información que se transfiere desde un agente JMX de la plataforma de clientes de gestión que lo supervisa. Los datos transmitidos son cifrados utilizando la criptografía (asimétrica) de clave pública, de manera que sólo el titular de la clave privada correspondiente puede descifrar los datos. Esto previene a las aplicaciones de análisis de paquetes de que intercepten la comunicación.El hacer uso de este dispositivo requiere que los dos extremos de la conexión tengan el SSL configurado, lo que implica la generación de un par de claves y un certificado digital. Los detalles están fuera del alcance de este artículo, lea el excelente tutorial de Greg Travis, "Uso de JSSE para la segura comunicación de socket," para obtener más información (ver Recursos).

Las buenas noticias es que una vez generadas el par de claves y el certificado, no es necesario modificar el código de clientes de gestión al hacer uso del SSL. Se puede activar el cifrado con sólo utilizar ciertas opciones de línea de comandos. En primer lugar, la aplicación Java que desea supervisar o administrar debe iniciarse con las siguientes opciones:

-Dcom.sun.management.jmxremote.ssl.need.client.auth=true
-Djavax.net.ssl.keyStore=<keystore-location>
-Djavax.net.ssl.trustStore=<truststore-location>
-Djavax.net.ssl.keyStoreType=<keystore-type>
-Djavax.net.ssl.keyStorePassword=<keystore-password>
-Djavax.net.ssl.trustStoreType=<truststore-type>
-Djavax.net.ssl.trustStorePassword=<truststore-password>

Los clientes de gestión que deseen comunicarse con la plataforma, tienen que ser lanzados con un subconjunto de las opciones anteriores: Se puede omitir la primera y las dos últimas líneas. Si el cliente es JConsole, puede transferir estas opciones cuando se inicia la GUI con la sintaxis de línea de comandos -J, la cual transfiere las opciones de Java a través de la JVM.

Una vez más, el tutorial "Uso de JSSE para la segura comunicación de socket" puede ofrecer más detalles sobre estas opciones individuales.


Conclusión

Esperamos haberle estimulado a conocer más acerca de la API de gestión de la plataforma Java 5.0. Así como la llegada de Java Management Extensions proporciona a los desarrolladores y administradores de empresa de Java una forma estandarizada para supervisar y controlar sus implementaciones, por lo que la introducción de la API java.lang.management en Java 5.0, le ofrece los medios para mirar por debajo de la capucha de la misma plataforma en la que se ejecutan sus aplicaciones.

Los MXBeans son bastante sencillos de obtener y utilizar, si están manteniendo agrupaciones de hebras y pestañas en una aplicación ejecutándose localmente o comprobando de forma segura el uso de la memoria de un programa de misión crítica que requiera la atención en otras partes de la intranet. Los MXBeans desempeñan un papel fundamental en ayudarle a entender más sobre el mundo en que él se ejecuta su código, si está analizando y tratando de comprender las características de las implementaciones Java desconocidas de una manera no intrusiva, o compilando sus propias herramientas de supervisión del rendimiento y creación de perfiles.

Como "la habilidad de diagnosticar, supervisión y gestión" es uno de los temas clave para el próximo release 6.0 de la plataforma Java, esta API se establece para tener un rol cada vez más importante en el futuro de la tecnología Java.

Recursos

Aprender

Comentar

Comentarios

developerWorks: Ingrese

Los campos obligatorios están marcados con un asterisco (*).


¿Necesita un IBM ID?
¿Olvidó su IBM ID?


¿Olvidó su Password?
Cambie su Password

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


La primera vez que inicie sesión en developerWorks, se creará un perfil para usted. La información en su propio perfil (nombre, país/región y nombre de la empresa) se muestra al público y acompañará a cualquier contenido que publique, a menos que opte por la opción de ocultar el nombre de su empresa. Puede actualizar su cuenta de IBM en cualquier momento.

Toda la información enviada es segura.

Elija su nombre para mostrar



La primera vez que inicia sesión en developerWorks se crea un perfil para usted, teniendo que elegir un nombre para mostrar en el mismo. Este nombre acompañará el contenido que usted publique en developerWorks.

Por favor elija un nombre de 3 - 31 caracteres. Su nombre de usuario debe ser único en la comunidad developerWorks y debe ser distinto a su dirección de email por motivos de privacidad.

Los campos obligatorios están marcados con un asterisco (*).

(Por favor elija un nombre de 3 - 31 caracteres.)

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


Toda la información enviada es segura.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=tecnologia Java
ArticleID=813978
ArticleTitle=Uso de los beans de gestión de la plataforma Java
publish-date=05162012