سؤال

لقد قمت بتعيين hibernate.generate_statistics=true وأحتاج الآن إلى تسجيل وحدات mbeans حتى أتمكن من رؤية الإحصائيات في وحدة تحكم jmx.يبدو أنني لا أستطيع الوصول إلى أي مكان ولا يبدو أن هذه مشكلة صعبة.ربما أقوم بجعل الأمور أكثر تعقيدًا، ولكن على أي حال حاولت حتى الآن:

  • لقد قمت بنسخ EhCacheProvider وطلبت منه إنشاء نسخة موسعة من CacheManager والتي أدت إلى زيادة تحميل init() واستدعاء ManagementService.registerMBeans(...) بعد التهيئة.تم تشغيل الكود بشكل جيد حتى الاستدعاء الفعلي لـ RegisterMBeans(...) والذي قد يتسبب في فشل تهيئة الموفر بسبب خطأ عام (لسوء الحظ لم أكتبه.) كان الدافع وراء هذا الأسلوب هو الأساليب المستخدمة في هذه الإرشادات التفصيلية لأداء liferay.
  • لقد قمت بإنشاء MBean الخاص بي باستخدام طريقة البدء التي تم تشغيل رمز مشابه لها هذا المثال لتسجيل mbeans jmx الخاص بـ 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.على أية حال، يبدو أنني أواجه مشكلة مماثلة عندما حاولت جمع الإحصائيات يدويًا، لأنني أحصل على جميع الأصفار حتى بعد النقر فوق تطبيقي لفترة قصيرة.

هل كانت مفيدة؟

المحلول 2

تم حلها.نظرًا لأنني لم أتمكن من رؤية جميع ذاكرات التخزين المؤقت للكيانات الخاصة بي، فقد اشتبهت في أنني لم أحصل على مثيل SessionFactory الصحيح.لقد بدأت بهذا السطر (راجع مثال رمز تسجيل jmx في الرابط الذي قدمته في السؤال):

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

وكانت النتيجة النهائية هي أن مدير ذاكرة التخزين المؤقت الذي انتهيت إليه في النهاية كان مثيلًا جديدًا وليس مثيلًا من سياق الثبات.لذلك حاولت إعادة البناء على النحو التالي:

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

ولكن هذا مجرد استثناء (لا أتذكر النص بالضبط؛شيء ما تأثير "لا يمكن تهيئة سياق الثبات.") لذلك لم يتبق لدي أي خيارات أخرى، أضفت حبة عديمة الحالة (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 إذا كنت تريد استرداد الإحصائيات يدويًا (وهو ما سأفعله على الأرجح على أي حال.) يمكنك العثور على مزيد من المعلومات حول كيفية استخدام كائنات ذاكرة التخزين المؤقت والإحصائيات في عينات التعليمات البرمجية ehcache.

إذا كان بإمكان أي شخص أن يزودني بطريقة للبحث بشكل ثابت عن مصنع الجلسة دون الحاجة إلى إنشاء حبة الجلسة الإضافية هذه، فأنا أرغب في سماع ذلك.

نصائح أخرى

تفترض الإجابة المذكورة أعلاه أنه يتم استخدام SingletonEhcacheProvider ويحتاج أيضًا إلى وحدة الفول utilmgr، ويستخدم هذا الحل الآخر وحدة بدء التشغيل ولا يقوم بافتراض المفردة

@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