2008-10-30 7 views
0

J'ai défini hibernate.generate_statistics = true et dois maintenant enregistrer les mbeans pour pouvoir afficher les statistiques dans la console jmx. Je n'arrive pas à aller quelque part et cela ne semble pas être un problème si difficile. Peut-être que je fais des choses trop compliquées, mais en tout cas jusqu'à présent, je l'ai essayé:Activation des statistiques ehcache dans jboss 4.2.1

  • Je copié EhCacheProvider et l'avait instancier une version étendue de CacheManager qui surcharge init() et a appelé ManagementService.registerMBeans (.. .) après l'initialisation. Le code s'est très bien passé jusqu'à l'appel effectif à registerMBeans (...) qui provoquerait l'échec de l'initialisation du provider avec une erreur générique (malheureusement je ne l'ai pas notée). Cette approche a été motivée par les méthodes utilisées en this liferay performance walkthrough.
  • J'ai créé mon propre MBean avec une méthode de démarrage qui a exécuté un code similaire à this example of registering ehcache's jmx mbeans. Tout a semblé fonctionner correctement et mon mbean apparaît dans la console de jmx mais rien pour net.sf.ehcache. J'ai depuis mis à jour ehcache à 1.5 (nous utilisions 1.3, je ne sais pas si c'est spécifique à jboss 4.2.1 ou juste quelque chose que nous avons choisi) et nous avons changé pour utiliser le SingletonEhCacheProvider et essayer de saisir manuellement les statistiques au lieu de traitant de l'enregistrement de mbean. Cependant, cela ne s'est pas vraiment amélioré. si je l'appelle getInstance() le CacheManager qui est retourné a seulement une copie de StandardQueryCache, mais les journaux jboss montrent que beaucoup d'autres caches ont été initialisés

EDIT (un pour chacune des entités mises en cache dans notre application.): Eh bien J'ai compris une chose ... la connexion via JConsole révèle les statistiques. Je suppose que ManagementFactory.getPlatformMBeanServer() ne vous donne pas le même serveur mbean que jboss utilise. Quoi qu'il en soit, il semble que je rencontre un problème similaire lorsque j'ai essayé de collecter les statistiques manuellement, parce que je reçois tous les zéros même après avoir cliqué un peu sur mon application.

Répondre

0

Résolu. Comme je ne voyais pas tous les caches pour mes entités, je soupçonnais que je n'obtenais pas la bonne instance de SessionFactory. J'ai commencé avec cette ligne (voir le code d'enregistrement exemple JMX dans le lien que j'ai fourni dans la question):

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

Le résultat final a été le gestionnaire de cache j'ai finalement fini avec était une nouvelle instance et non pas celui à partir du contexte de persistance. J'ai donc essayé refactoring comme:

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

mais juste jeté une exception, donc laissé aucune autre option (je ne me rappelle pas le texte exact quelque chose à l'effet de « ne peut pas initialiser le contexte de persistance. ») , J'ai ajouté un bean sans état (UtilMgr) à mon application et laissé la persistance injecter le bon SessionFactory. Voici que le haricot: méthode de UtilMgr si vous voulez récupérer les statistiques (qui est manuellement

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

Vous pouvez également utiliser cette getCacheManager():

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

et voici le code corrigé de la procédure pas à pas mentionné précédemment Ce que je ferai probablement de toute façon.) Vous pouvez trouver plus d'informations sur comment utiliser utiliser les objets Cache et Statistiques in the ehcache code samples.

Si quelqu'un peut me renseigner sur un moyen de rechercher statiquement l'usine de session sans avoir besoin de créatinine g ce haricot de session supplémentaire, j'aimerais l'entendre.

1

La réponse donnée ci-dessus suppose que SingletonEhcacheProvider est utilisé et il a aussi besoin de la fève de utilmgr, cette autre solution utilise un grain de démarrage et ne fait pas l'hypothèse 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); 
     } 
    } 
} 

}

Nous utilisons MbeanServerLocator comme jboss mbean serait le second serveur mbean dans des environnements comme linux.