Pergunta

Eu configurei hibernate.generate_statistics = true e agora tem que registrar os mbeans para que eu possa ver as estatísticas no console jmx. Eu não consigo obter qualquer lugar e isso não parece como ele deve ser um problema tão difícil. Talvez eu estou fazendo as coisas demasiado complicada, mas em qualquer caso, até agora eu tentei:

  • Copiei EhCacheProvider e teve que instanciar uma versão estendida do CacheManager que sobrecarregado init () e chamados ManagementService.registerMBeans (...) após a inicialização. O código tudo bem funcionou até a chamada real para registerMBeans (...) o que causaria a inicialização provedor para falhar com um erro genérico (infelizmente eu não anotá-la.) Esta abordagem foi motivada pelos métodos utilizados na este passo a passo desempenho liferay.
  • Eu criei meus próprios MBean com um método start que corria código semelhante ao este exemplo de registrar de ehcache jmx mbeans . Tudo parecia trabalho corretamente e meus shows MBean no console jmx mas nada para net.sf.ehcache.
  • Eu já ehcache atualizado para 1.5 (estávamos usando 1.3, não tenho certeza se que é específico para o JBoss 4.2.1 ou apenas algo que escolhemos a nós mesmos) e mudou para usando o SingletonEhCacheProvider e tentando apenas pegar manualmente as estatísticas em vez de lidar com o registro mbean. Não tem realmente ido melhor embora; se eu chamar getInstance () o CacheManager que é retornado só tem uma cópia do StandardQueryCache, mas registros jboss mostram que muitos outros caches foram inicializados (um para cada uma das entidades em cache em nossa aplicação.)

EDIT: Bem, eu descobri uma coisa ... conectar via JConsole não revelar os mbeans estatísticas. Eu acho que não ManagementFactory.getPlatformMBeanServer () não lhe dar o mesmo servidor mbean como jboss está usando. De qualquer forma, parece que eu estou encontrando um problema semelhante como quando eu tentei recolher as estatísticas manualmente, porque eu estou recebendo todos os zeros, mesmo após clicar através do meu aplicativo para um pouco.

Foi útil?

Solução 2

resolvido. Desde que eu não estava vendo todos os caches para meus entidades suspeitei eu não estava recebendo a instância SessionFactory direita. Eu comecei com esta linha (veja o código de registro exemplo JMX no link eu fornecido na pergunta):

SessionFactory sf = (new Configuration()).configure().buildSessionFactory();

O resultado final foi o Gerenciador de cache I finalmente acabou com era uma nova instância e não a partir do contexto de persistência. Então, eu tentei refatoração como:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("myPersistenceUnit");
return ((EntityManagerFactoryImpl)emf).getSessionFactory();

mas que jogou apenas uma exceção (não me lembro o texto exato, algo para o efeito de "não pode inicializar persistência contexto") Assim, deixou sem outras opções, eu adicionei um feijão stateless (UtilMgr) para o meu pedido e deixe persistência injetar o SessionFactory correta. Aqui está o bean:

import javax.ejb.Stateless;
import javax.persistence.PersistenceUnit;
import net.sf.ehcache.CacheManager;
import org.hibernate.SessionFactory;

@Stateless
public class UtilMgrBean implements UtilMgr {
    // NOTE: rename as necessary
    @PersistenceUnit(unitName = "myPersistenceCtx")
    private SessionFactory sessionFactory;

    public SessionFactory getSessionFactory() {
        return this.sessionFactory;
    }

    public CacheManager getCacheManager() {
        return CacheManager.getInstance(); // NOTE: assumes SingletonEhCacheProvider
    }
}

e aqui está o código corrigido a partir da explicação passo a passo mencionado anteriormente:

try {
    // NOTE: lookupBean is a utility method in our app we use for jndi lookups.
    //   replace as necessary for your application.
    UtilMgr utilMgr = (UtilMgr)Manager.lookupBean("UtilMgrBean", UtilMgr.class);
    SessionFactory sf = utilMgr.getSessionFactory();
    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();

    // NOTE: replace myAppName as necessary
    ObjectName on = new ObjectName("Hibernate:type=statistics,application=myAppName");

    // Enable Hibernate JMX Statistics
    StatisticsService statsMBean = new StatisticsService();
    statsMBean.setSessionFactory(sf);
    statsMBean.setStatisticsEnabled(true);
    mbs.registerMBean(statsMBean, on);

    CacheManager cacheMgr = utilMgr.getCacheManager();
    ManagementService.registerMBeans(cacheMgr, mbs, true, true, true, true);
} catch(Throwable t) {
    throw new RuntimeException(t);
}

Você também pode usar esse método getCacheManager () de UtilMgr se você deseja recuperar as estatísticas manualmente (que é o que eu provavelmente vou fazer de qualquer maneira.) Você pode encontrar mais informações sobre como usar usar o cache e Estatística objetos nas amostras de código ehcache.

Se alguém pode encher-me sobre uma maneira de estaticamente procurar o fábrica de sessão sem a necessidade de criar este bean de sessão extra, eu adoraria ouvi-lo.

Outras dicas

A resposta dada acima assume que SingletonEhcacheProvider está sendo usado e ele também precisa do feijão utilmgr, esta outra solução usa um bean de inicialização e não fazer a suposição de Singleton

@Name("hibernateStatistics")
@Scope(ScopeType.APPLICATION)
@Startup
public class HibernateUtils {
@In
private EntityManager entityManager;

@Create
public void onStartup() {
    if (entityManager != null) {
        try {
            //lookup the jboss mbean server
            MBeanServer beanServer = org.jboss.mx.util.MBeanServerLocator.locateJBoss();
            StatisticsService mBean = new StatisticsService();
            ObjectName objectName = new ObjectName("Hibernate:type=statistics,application=<application-name>");
            try{
                beanServer.unregisterMBean(objectName);
            }catch(Exception exc) {
                //no problems, as unregister is not important
            }
            SessionFactory sessionFactory = ((HibernateSessionProxy) entityManager.getDelegate()).getSessionFactory();
            mBean.setSessionFactory(sessionFactory);
            beanServer.registerMBean(mBean, objectName);

            if (sessionFactory instanceof SessionFactoryImplementor ){
                CacheProvider cacheProvider = ((SessionFactoryImplementor)sessionFactory).getSettings().getCacheProvider();
                if (cacheProvider instanceof EhCacheProvider)  {
                    try{
                        Field field = EhCacheProvider.class.getDeclaredField("manager");
                        field.setAccessible(true);
                        CacheManager cacheMgr = (CacheManager) field.get(cacheProvider);
                        ManagementService.registerMBeans(cacheMgr, beanServer, true, true, true, true);
                    }catch(Exception exc) {
                        //do nothing
                        exc.printStackTrace();
                    }
                }
            }

        } catch (Exception e) {
            throw new RuntimeException("The persistence context " + entityManager.toString() + "is not properly      configured.", e);
        }
    }
 }

}

Nós usamos MbeanServerLocator como mbean jboss seria o segundo servidor mbean em ambientes como o Linux.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top