Domanda

Ho impostato hibernate.generate_statistics = true e ora ho bisogno di registrare gli mbeans in modo che io possa vedere le statistiche nella console jmx. Non riesco ad arrivare da nessuna parte e questo non sembra che dovrebbe essere un problema così difficile. Forse sto rendendo le cose troppo complicate, ma in ogni caso finora ho provato:

  • Ho copiato EhCacheProvider e ho avuto un'istanza di una versione estesa di CacheManager che ha sovraccaricato init () e chiamato ManagementService.registerMBeans (...) dopo l'inizializzazione. Il codice è andato tutto bene fino alla chiamata effettiva a registerMBeans (...) che avrebbe causato il fallimento dell'inizializzazione del provider con un errore generico (sfortunatamente non l'ho annotato). Questo approccio è stato motivato dai metodi usati in questa procedura dettagliata per le prestazioni della vita notturna.
  • Ho creato il mio MBean con un metodo di avvio che eseguiva un codice simile a questo esempio di registrazione dei jmx mbeans di ehcache . Sembrava che tutto funzionasse correttamente e il mio mbean si presentasse nella console jmx ma niente per net.sf.ehcache.
  • Da allora ho aggiornato ehcache a 1.5 (stavamo usando 1.3, non sono sicuro che fosse specifico di jboss 4.2.1 o solo qualcosa che abbiamo scelto noi stessi) e sono passato a usare SingletonEhCacheProvider e cercando di afferrare manualmente le statistiche invece di gestire la registrazione mbean. In realtà non è andata meglio; se chiamo getInstance () il CacheManager restituito ha solo una copia di StandardQueryCache, ma i registri jboss mostrano che sono state inizializzate molte altre cache (una per ciascuna delle entità memorizzate nella cache nella nostra applicazione.)

EDIT: Beh, ho capito una cosa ... connettersi tramite JConsole rivela le statistiche mbeans. Immagino che ManagementFactory.getPlatformMBeanServer () non ti dia lo stesso server mbean di jboss. Ad ogni modo sembra che stia riscontrando un problema simile a quando ho provato a raccogliere manualmente le statistiche, perché sto ottenendo tutti gli zeri anche dopo aver fatto clic un po 'sulla mia app.

È stato utile?

Soluzione 2

risolto. Dal momento che non vedevo tutte le cache per le mie entità sospettavo di non avere l'istanza SessionFactory corretta. Ho iniziato con questa riga (vedi il codice di registrazione jmx di esempio nel link che ho fornito nella domanda):

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

Il risultato finale è stato il gestore della cache con cui alla fine sono stata una nuova istanza e non quella del contesto di persistenza. Quindi ho provato a refactoring come:

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

ma questo ha appena generato un'eccezione (non ricordo il testo esatto; qualcosa per l'effetto di " impossibile inizializzare il contesto di persistenza. ") Quindi lasciato senza altre opzioni, ho aggiunto un bean stateless (UtilMgr ) alla mia applicazione e lasciare che la persistenza inietti la SessionFactory corretta. Ecco quel 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
    }
}

ed ecco il codice corretto dal walkthrough menzionato in precedenza:

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

Puoi anche usare questo metodo getCacheManager () di UtilMgr se vuoi recuperare manualmente le statistiche (che è quello che probabilmente farò comunque.) Puoi trovare maggiori informazioni su come usare gli oggetti Cache e Statistics negli esempi di codice ehcache.

Se qualcuno mi può compilare un modo per cercare staticamente la factory di sessione senza la necessità di creare questo bean di sessione extra, mi piacerebbe ascoltarlo.

Altri suggerimenti

La risposta di cui sopra presuppone che sia utilizzato SingletonEhcacheProvider e che abbia anche bisogno del bean utilmgr, questa altra soluzione utilizza un bean di avvio e non assume l'assunto 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);
        }
    }
 }

}

Usiamo MbeanServerLocator come jboss mbean sarebbe il secondo server mbean in ambienti come Linux.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top