JBoss 4.2.1でehcache統計を有効にする
-
05-07-2019 - |
質問
hibernate.generate_statistics = trueを設定し、jmxコンソールで統計を表示できるようにmbeanを登録する必要があります。私はどこにも行けないようで、これはそんなに難しい問題ではないようです。たぶん私は物事を過度に複雑にしていますが、いずれにせよ今まで試しました:
- EhCacheProviderをコピーし、初期化後にinit()をオーバーロードし、ManagementService.registerMBeans(...)を呼び出すCacheManagerの拡張バージョンをインスタンス化しました。 registerMBeans(...)の実際の呼び出しまでコードはすべて正常に実行されたため、プロバイダーの初期化は一般的なエラーで失敗しました(残念ながら書きませんでした)。このアプローチは、このliferayパフォーマンスウォークスルー。
- ehcacheのjmx mbeanを登録するこの例。すべてが正しく動作しているように見え、jbeanコンソールにmbeanが表示されますが、net.sf.ehcacheには何も表示されません。
- ehcacheを1.5にアップグレードしてから(1.3を使用していましたが、jboss 4.2.1に固有なのか、自分で選んだものなのかわかりません)、SingletonEhCacheProviderを使用して、手動で統計を取得するように変更しましたmbean登録の処理。しかし、実際にはこれ以上改善されていません。 getInstance()を呼び出すと、返されるCacheManagerにはStandardQueryCacheのコピーのみが含まれますが、jbossログには他の多くのキャッシュが初期化されていることが示されます(アプリケーションのキャッシュされたエンティティごとに1つ)
編集:さて、私は1つのことを理解しました... JConsoleを介して接続すると統計mbeanが明らかになります。 ManagementFactory.getPlatformMBeanServer()は、jbossが使用しているのと同じmbeanサーバーを提供しないと思います。とにかく、統計情報を手動で収集しようとしたときと同じような問題が発生しているようです。アプリを少しクリックした後でも、すべてゼロになっているためです。
解決 2
解決済み。エンティティのすべてのキャッシュが表示されていなかったため、適切な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()メソッドを使用することもできます(とにかくこれを行うと思われます)。CacheおよびStatisticsオブジェクトの使用方法に関する詳細情報を見つけることができます ehcacheコードサンプル。
この追加のセッションBeanを作成することなく、セッションファクトリを静的にルックアップする方法について誰かが私に記入できるなら、私はそれを聞きたいです。
他のヒント
上記の回答では、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を使用します。