0

hibernate.generate_statistics=true を設定し、mbeans を登録して、jmx コンソールで統計を確認できるようにする必要があります。どこにもたどり着けないようで、これはそれほど難しい問題ではないようです。多分私は物事を複雑にしすぎているのかもしれませんが、いずれにせよこれまでに私は試しました:

  • EhCacheProvider をコピーし、初期化後に init() をオーバーロードして ManagementService.registerMBeans(...) を呼び出す CacheManager の拡張バージョンをインスタンス化しました。registerMBeans(...) への実際の呼び出しまで、コードはすべて正常に実行されました。これにより、プロバイダーの初期化が一般的なエラーで失敗します (残念ながら、書き留めていませんでした)。このアプローチは、このライフレイで使用されるメソッドによって動機付けられました。パフォーマンスのウォークスルー。
  • ehcache の jmx mbeans を登録するこの例と同様のコードを実行する start メソッドを使用して、独自の MBean を作成しました。すべてが正しく動作しているように見え、mbean は jmx コンソールに表示されますが、net.sf.ehcache には何も表示されません。
  • それ以来、ehcache を 1.5 にアップグレードし (1.3 を使用していましたが、それが jboss 4.2.1 に固有のものなのか、自分で選択したものなのかはわかりません)、SingletonEhCacheProvider を使用するように変更し、手動で統計を取得しようとしました。 mbean 登録。ただし、実際には改善されていません。getInstance() を呼び出すと、返される CacheManager には StandardQueryCache のコピーしかありませんが、jboss ログには、他の多くのキャッシュが初期化されていることが示されます (アプリケーション内のキャッシュされたエンティティごとに 1 つ)。

編集:まあ、私は1つのことを理解しました... JConsoleを介して接続すると、統計mbeansが明らかになります。ManagementFactory.getPlatformMBeanServer() は、jboss が使用しているのと同じ mbean サーバーを提供しないと思います。とにかく、統計を手動で収集しようとしたときと同様の問題が発生しているようです。アプリを少しクリックした後でもすべてゼロになるためです。

4

2 に答える 2

1

上記の回答は、SingletonEhcacheProvider が使用されており、utilmgr Bean も必要であることを前提としています。この他のソリューションはスタートアップ 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);
        }
    }
 }

}

jboss mbean は Linux のような環境で 2 番目の mbean サーバーになるため、MbeanServerLocator を使用します。

于 2010-04-07T09:34:38.790 に答える
0

解決しました。エンティティのすべてのキャッシュが表示されていなかったため、適切なSessionFactoryインスタンスを取得していないと思われました。私はこの行から始めました(質問で提供したリンクのjmx登録コードの例を参照してください):

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

最終的には、永続コンテキストからのインスタンスではなく、新しいインスタンスになってしまったキャッシュマネージャーができあがりました。だから私は次のようにリファクタリングを試みました:

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

しかし、それは例外を投げただけです(正確なテキストを覚えていません。「永続コンテキストを初期化できません」という効果があります)。そこで、他のオプションを残さずに、ステートレスBean(UtilMgr)をアプリケーションに追加しました。永続性が正しいSessionFactoryを注入するようにします。これがその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
    }
}

前述のウォークスルーから修正されたコードは次のとおりです。

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()メソッドを使用することもできます(これはおそらくとにかく実行します)。ehcacheコードサンプルで、CacheオブジェクトとStatisticsオブジェクトの使用方法に関する詳細情報を見つけることができます。

この追加のセッションBeanを作成せずに、セッションファクトリを静的にルックアップする方法について誰かが私に記入してくれるなら、それを聞いてみたいです。

于 2008-10-30T21:19:34.140 に答える