Вопрос

Я установил 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 и пытаюсь просто вручную получить статистику вместо того, чтобы иметь дело с регистрация mbean.Однако на самом деле дела пошли не лучше;если я вызываю getInstance(), возвращаемый CacheManager содержит только копию StandardQueryCache, но журналы jboss показывают, что было инициализировано множество других кешей (по одному для каждого из кэшированных объектов в нашем приложении).

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

Это было полезно?

Решение 2

Решено.Поскольку я не видел всех кэшей своих объектов, я подозревал, что получаю не тот экземпляр 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);
}

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

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

Другие советы

В ответе, приведенном выше, предполагается, что используется 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top