Pregunta

He establecido hibernate.generate_statistics = true y ahora necesito registrar los mbeans para poder ver las estadísticas en la consola jmx. Parece que no puedo llegar a ninguna parte y esto no parece ser un problema tan difícil. Tal vez estoy haciendo las cosas demasiado complicadas, pero en cualquier caso hasta ahora lo he intentado:

  • Copié EhCacheProvider e instalé una versión extendida de CacheManager que sobrecargó init () y llamó a ManagementService.registerMBeans (...) después de la inicialización. Todo el código funcionó bien hasta que la llamada real a registerMBeans (...) causó que la inicialización del proveedor fallara con un error genérico (desafortunadamente no lo escribí). Este enfoque fue motivado por los métodos utilizados en este tutorial de rendimiento a lo largo de la vida.
  • Creé mi propio MBean con un método de inicio que ejecutaba un código similar a este ejemplo de registro de jmx mbeans de ehcache . Todo pareció funcionar correctamente y mi mbean aparece en la consola jmx pero nada para net.sf.ehcache.
  • Desde entonces, actualicé ehcache a 1.5 (estábamos usando 1.3, no estoy seguro de si eso es específico de jboss 4.2.1 o simplemente algo que elegimos nosotros mismos) y cambié a usar SingletonEhCacheProvider e intenté simplemente obtener las estadísticas manualmente en lugar de Tratando con el registro de mbean. Sin embargo, no ha ido mejor; si llamo a getInstance (), el CacheManager que se devuelve solo tiene una copia de StandardQueryCache, pero los registros de jboss muestran que muchos otros cachés se han inicializado (uno para cada una de las entidades en caché en nuestra aplicación).

EDITAR: Bueno, he descubierto una cosa ... la conexión a través de JConsole revela las estadísticas mbeans. Supongo que ManagementFactory.getPlatformMBeanServer () no te da el mismo servidor mbean que está usando jboss. De todos modos, parece que estoy encontrando un problema similar cuando intenté recopilar las estadísticas manualmente, porque obtengo todos ceros, incluso después de hacer clic en mi aplicación por un momento.

¿Fue útil?

Solución 2

Resuelto. Como no estaba viendo todos los cachés de mis entidades, sospeché que no estaba obteniendo la instancia correcta de SessionFactory. Comencé con esta línea (vea el ejemplo de código de registro jmx en el enlace que proporcioné en la pregunta):

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

El resultado final fue el administrador de caché con el que finalmente terminé, era una nueva instancia y no la del contexto de persistencia. Así que intenté refactorizar como:

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

pero eso acaba de lanzar una excepción (no recuerdo el texto exacto; algo en el efecto de " no puede inicializar el contexto de persistencia. ") Así que sin más opciones, agregué un bean sin estado (UtilMgr ) a mi aplicación y deje que la persistencia inyecte el SessionFactory correcto. Aquí está ese frijol:

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

y aquí está el código corregido del tutorial 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);
}

También puede usar este método getCacheManager () de UtilMgr si desea recuperar las estadísticas manualmente (que es lo que probablemente haré de todos modos). Puede encontrar más información sobre cómo usar los objetos de caché y estadísticas en los ejemplos de código de ehcache.

Si alguien puede informarme sobre la forma de buscar estáticamente la fábrica de sesiones sin la necesidad de crear este bean de sesión adicional, me encantaría escucharlo.

Otros consejos

La respuesta dada anteriormente asume que se está utilizando SingletonEhcacheProvider y también necesita el bean utilmgr, esta otra solución usa un bean de inicio y no hace la suposición 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);
        }
    }
 }

}

Usamos MbeanServerLocator ya que jboss mbean sería el segundo servidor mbean en entornos como Linux.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top