Включение статистики ehcache в jboss 4.2.1

Я установил hibernate.generate_statistics=true, и теперь мне нужно зарегистрировать mbeans, чтобы я мог видеть статистику в консоли jmx. Кажется, я никуда не могу попасть, и это не похоже на то, что это должно быть такой сложной проблемой. Может быть, я слишком усложняю, но в любом случае до сих пор я пытался:

  • Я скопировал EhCacheProvider и создал расширенную версию CacheManager, которая перегружала init() и вызывала ManagementService.registerMBeans(...) после инициализации. Весь код работал нормально до фактического вызова registerMBeans(...), что привело бы к сбою инициализации провайдера с общей ошибкой (к сожалению, я не записал ее). Этот подход был мотивирован методами, используемыми в это пошаговое руководство по производительности liferay.
  • Я создал свой собственный MBean с методом запуска, который запускал код, аналогичный этот пример регистрации jmx mbeans ehcache. Казалось, все работает правильно, и мой mbean отображается в консоли jmx, но ничего для net.sf.ehcache.
  • С тех пор я обновил ehcache до 1.5 (мы использовали 1.3, не уверен, что это конкретно для jboss 4.2.1 или просто что-то, что мы выбрали сами) и перешел на использование SingletonEhCacheProvider и попытался просто вручную получить статистику вместо того, чтобы иметь дело с регистрация мбэн. Однако на самом деле ситуация не улучшилась; если я вызываю getInstance(), возвращаемый CacheManager имеет только копию StandardQueryCache, но журналы jboss показывают, что многие другие кэши были инициализированы (по одному для каждого из кэшированных объектов в нашем приложении).

РЕДАКТИРОВАТЬ: Ну, я понял одну вещь... подключение через JConsole действительно показывает mbeans статистики. Я предполагаю, что ManagementFactory.getPlatformMBeanServer() не дает вам тот же сервер mbean, который использует jboss. В любом случае, похоже, что я столкнулся с той же проблемой, что и при попытке собрать статистику вручную, потому что я получаю все нули даже после небольшого щелчка по моему приложению.


person Matt S.    schedule 30.10.2008    source источник


Ответы (2)


Приведенный выше ответ предполагает, что используется SingletonEhcacheProvider, и ему также нужен bean-компонент utilmgr, это другое решение использует стартовый bean-компонент и не делает предположение об одноэлементном

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

}

Мы используем MbeanServerLocator, так как jboss mbean будет вторым сервером mbean в таких средах, как Linux.

person sans_sense    schedule 07.04.2010

Решено. Поскольку я не видел все кеши для своих сущностей, я подозревал, что не получаю правильный экземпляр SessionFactory. Я начал с этой строки (см. пример регистрационного кода jmx в ссылке, которую я указал в вопросе):

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

Конечным результатом стало то, что менеджер кеша, с которым я в конечном итоге оказался, был новым экземпляром, а не тем, что был в контексте персистентности. Итак, я попытался выполнить рефакторинг как:

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

но это просто вызвало исключение (я не помню точный текст; что-то вроде «невозможно инициализировать контекст сохранения».) Поэтому, не имея других вариантов, я добавил в свое приложение bean-компонент без сохранения состояния (UtilMgr) и пусть постоянство введет правильный SessionFactory. Вот эта фасоль:

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

и вот исправленный код из ранее упомянутого пошагового руководства:

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

Вы также можете использовать этот метод UtilMgr getCacheManager(), если хотите получить статистику вручную (что я, вероятно, и сделаю). Вы можете найти дополнительную информацию о том, как использовать объекты Cache и Statistics в примерах кода ehcache.

Если кто-нибудь может рассказать мне о способе статического поиска фабрики сеансов без необходимости создания этого дополнительного компонента сеанса, я бы хотел это услышать.

person Matt S.    schedule 30.10.2008