Java Management Extensions (JMX)
Introdução
- Queremos instrumentar aplicações para que sejam gerenciadas remotamente
- Monitoração remota
- Está no ar?
- Que recursos estão sendo consumidos?
- Configuração remota
- Verificar e alterar valor de parâmetros de configuração
- etc.
- JMX é uma tecnologia do mundo Java que permite fazer isso com facilidade
- JDK 1.5 inclui uma console de gerência (jconsole)
- Mas você pode escrever sua própria console de gerência
- Muitas aplicações importantes são gerenciáveis via JMX
Uma demo
- A demo vem daqui
- Use Java JDK 1.5 que já inclui JMX
- Uma console de gerência simples já vem com o JDK
- Instruções para a demo
- Download da aplicação aqui
- javac com/oreilly/onjava/jmxexample/SimpleApplication.java
- Rode a aplicação
- java -Dcom.sun.management.jmxremote -classpath .
com.oreilly.onjava.jmxexample.SimpleApplication
- Crie algumas janelas clicando no botão

-
- Inicie jconsole, a console de gerência
- jconsole acha todas as aplicações no localhost

- Escolha sua aplicação e cique em Connect
- jconsole dá um sumário de recursos da aplicação

- Veja algumas telas de jconsole (abaixo)
- Monitoração do uso de memória pela aplicação

- Examinando a situação dos threads

- Monitorando o número de classes carregadas

- Lista de MBeans ativos e disponíveis no agente JMX da aplicação

- Examinando informação sobre a JVM da aplicação

- É através de um MBean que você pode expor informação
customizada de gerência
- Info de configuração (número de threads, tamanho de cache, etc. etc.)
- Com JMX e MBeans, você pode não só monitorar a aplicação mas também interagir com
ela
- Exemplo:
- Podemos mandar executar o garbage collector da aplicação (ver figura)

- Tammbém podemos monitorar aplicações remotas (em outras máquinas)
- Também podemos impor restrições de acesso (via senha, por exemplo)
- Agora, vamos ver como fazer essas coisas uns exemplos simples
Arquitetura do JMX
- A entidade básica que expõe informação de gerência é o MBean
- Portanto o MBean é usado para intrumentar um recurso que se quer gerenciar
- Um MBean expõe uma interface de gerência para um recurso
- Uma vez que um recurso está instrumentado com um MBean, pode ser gerenciado usando um agente JMX
- MBeans nada sabem do agente
- Uma aplicação de gerência conversa com agentes para realizar gerência

- Criar MBeans é muito simples, tão simples quanto beans normais
- Uso de nomes padronizados (get, set, ...)
- Portanto, não há grande investimento para poder deixar uma aplicação gerenciável
- A arquitetura também permite usar uma forma de notificação
- Isso é importante em qualquer aplicação de gerência
- A aplicação pode soltar um grito "Estou mal!" em ter que esperar que a
aplicação de gerência peça informação para a aplicação
-
- Há vários tipos de MBeans (standard MBeans, dynamic MBeans, open MBeans e model MBeans)
- Só falaremos de standard MBeans aqui
Standard MBeans
- Define-se um MBean padrão definindo uma interface XptoMBean
- A implementação da interface chama-se Xpto
- Cada método define
- Um atributo de gerência que pode ser lido (set...) e/ou gravado (set...); ou
- Um método de gerência que pode ser chamado
A interface MBean
package com.example.mbeans;
public interface HelloMBean {
public void sayHello();
public int add(int x, int y);
public String getName();
public int getCacheSize();
public void setCacheSize(int size);
}
- Temos dois atributos (name, cacheSize) e dois métodos de gerência (sayHello, add)
Implementação de um MBean
package com.example.mbeans;
public class Hello implements HelloMBean {
public void sayHello() {
System.out.println("hello, world");
}
public int add(int x, int y) {
return x + y;
}
public String getName() {
return this.name;
}
public int getCacheSize() {
return this.cacheSize;
}
public synchronized void setCacheSize(int size) {
this.cacheSize = size;
System.out.println("Cache size now " + this.cacheSize);
}
private final String name = "Reginald";
private int cacheSize = DEFAULT_CACHE_SIZE;
private static final int DEFAULT_CACHE_SIZE = 200;
}
- Claro que o exemplo acima não ;e bem o que se chama "gerência" mas dá para
imaginar que poderíamos expor qualquer informação de gerência
Gerenciando um recurso
- A gerência de um recurso é feito com um agente JMX
- A parte principal do agente é o "MBean server" no qual os MBeans são
registrados para que aplicações de gerência possam achá-las
- Eis um exemplo simples dentro de nossa aplicação:
package com.example.mbeans;
import java.lang.management.*;
import javax.management.*;
public class Main {
public static void main(String[] args) throws Exception {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("com.example.mbeans:type=Hello");
Hello mbean = new Hello();
mbs.registerMBean(mbean, name);
System.out.println("Waiting forever...");
Thread.sleep(Long.MAX_VALUE);
}
}
- O agente obtém um MBean server rodando na máquina
- Se não houver, um será criado automaticamente dentro de getPlatformMBeanServer()
- Um objeto especial que dá um nome ao bean é criado ("name")
- Cada MBean tem que ter um nome
- O nome consiste de um domínio (com.example.mbeans) e de uma lista de propriedades
(type=Hello)
- Em seguida, o MBean é criado e registrado junto ao MBean server
- Em seguida, nossa aplicação espera "para sempre"
- Na prática, ela faria seu trabalho
- Aqui, ela espera enquanto operações de gerência são feitas (através do jconsole)
Execução do exemplo
- $ cd work_dir/jmx_examples/Essential
- Compile
- $ javac com/example/mbeans/*.java
- Inicie a aplicação e habilite a monitoração local (no mmesmo host)
- $ java -classpath . -Dcom.sun.management.jmxremote com.example.mbeans.Main
- Inicie a console de gerência

- Conecte à sua aplicação e veja um sumário de recursos consumidos

- Clique na orelha MBeans
- O lado esquerdo mostra os MBeans registrados no MBean server

- Abra com.example.mbeans e clique no MBean Hello
- Veja os atributos do MBean

- Altere CacheSize para 150
- Uma mensagem de confirmação deverá aparecer na console da aplicação
- Clique na orelha Operations e clique em sayHello
- Uma dialog box avisa que a operação foi chamada
- A console da aplicação diz: hello, world
- Some dois inteiros com "add"
- A resposta é dada pelo próprio jconsole
- Clique em Connection e Exit
Envio de Notificações
- MBeans podem gerar notificações
- Importante para sinalizar eventos importantes para a console de gerência
- Use-se o conhecido padrão observer (arquitetura publish-subscribe)
- Cada notificação tem uma fonte, um número de sequência, etc.
Interface NotificationBroadcaster
- O exemplo é como o de cima mas gera notificações
package com.example.mbeans;
import javax.management.*;
public class Hello
extends NotificationBroadcasterSupport implements HelloMBean {
public void sayHello() {
System.out.println("hello, world");
}
public int add(int x, int y) {
return x + y;
}
public String getName() {
return this.name;
}
public int getCacheSize() {
return this.cacheSize;
}
public synchronized void setCacheSize(int size) {
int oldSize = this.cacheSize;
this.cacheSize = size;
System.out.println("Cache size now " + this.cacheSize);
Notification n =
new AttributeChangeNotification(this,
sequenceNumber++,
System.currentTimeMillis(),
"CacheSize changed",
"CacheSize",
"int",
oldSize,
this.cacheSize);
sendNotification(n);
}
@Override
public MBeanNotificationInfo[] getNotificationInfo() {
String[] types = new String[] {
AttributeChangeNotification.ATTRIBUTE_CHANGE
};
String name = AttributeChangeNotification.class.getName();
String description = "An attribute of this MBean has changed";
MBeanNotificationInfo info =
new MBeanNotificationInfo(types, name, description);
return new MBeanNotificationInfo[] {info};
}
private final String name = "Reginald";
private int cacheSize = DEFAULT_CACHE_SIZE;
private static final int DEFAULT_CACHE_SIZE = 200;
private long sequenceNumber = 1;
}
- O MBean herda de NotificationBroadcasterSupport qye implementa a interface
NotificationEmitter
- A notificação é construída como classe AttributeChangeNotification com os seguintes
parâmetros:
- A fonte da notificação
- Um número de sequência
- Um timestamp
- O conteúdo da mensagem de notificação
- O nome do atributo que mudou
- O tipo do atributo que mudou
- O valor anterior
- O valor novo
- MBeanNotification é usado para informar as características das diferentes
notificações enviadas pelo MBean
Execução do exemplo
- $ cd work_dir/jmx_examples/Notification
- Compile
- $ javac com/example/mbeans/*.java
- Inicie a aplicação
- $ java -classpath . -Dcom.sun.management.jmxremote com.example.mbeans.Main
- Inicie jconsole e conecte à aplicação
- Vai até a orelha Notifications do MBean Hello
- Clique em Subscribe
- Em Attributes, altere o cacheSize para 150 e examine as notificações

Finalmente ...
- Tem muito mais a ser discutido sobre JMX
- Dynamic MBeans
- Gerência remota
- Segurança (para que apenas pessoas autorizadas possam gerenciar aplicações)
- etc.
Bibliografia
programa