休眠(帶有Spring支持)
使用JMX公開Hibernate統計信息非常簡單 ,但是當使用JPA API獲取基礎SessionFactory
時,需要一些討厭的解決方法
class JmxLocalContainerEntityManagerFactoryBean() extends LocalContainerEntityManagerFactoryBean {override def createNativeEntityManagerFactory() = {val managerFactory = super.createNativeEntityManagerFactory()registerStatisticsMBean(managerFactory)managerFactory}def registerStatisticsMBean(managerFactory: EntityManagerFactory) {managerFactory match {case impl: EntityManagerFactoryImpl =>val mBean = new StatisticsService();mBean.setStatisticsEnabled(true)mBean.setSessionFactory(impl.getSessionFactory);val name = new ObjectName("org.hibernate:type=Statistics,application=spring-pitfalls")ManagementFactory.getPlatformMBeanServer.registerMBean(mBean, name);case _ =>}}}
請注意,我已經創建了Springs內置LocalContainerEntityManagerFactoryBean
的子類。 通過重寫createNativeEntityManagerFactory()
方法,我可以訪問EntityManagerFactory
并嘗試將其向下轉換為org.hibernate.ejb.EntityManagerFactoryImpl
我們能夠注冊Hibernate Mbean。
還有一件事。 顯然,我們必須使用自定義子類而不是org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
。 另外,為了收集實際的統計信息,而不是一直看到零,我們必須設置hibernate.generate_statistics
標志。
@Bean
def entityManagerFactoryBean() = {val entityManagerFactoryBean = new JmxLocalContainerEntityManagerFactoryBean()entityManagerFactoryBean.setDataSource(dataSource())entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter())entityManagerFactoryBean.setPackagesToScan("com.blogspot.nurkiewicz")entityManagerFactoryBean.setJpaPropertyMap(Map("hibernate.hbm2ddl.auto" -> "create","hibernate.format_sql" -> "true","hibernate.ejb.naming_strategy" -> classOf[ImprovedNamingStrategy].getName,"hibernate.generate_statistics" -> true.toString).asJava)entityManagerFactoryBean
}
這是我們希望在JvisualVM中看到的示例(不要忘記安裝所有插件!):

另外,我們獲得了一個不錯的Hibernate日志記錄:
HQL: select generatedAlias0 from Book as generatedAlias0, time: 10ms, rows: 20
高速緩存
監視緩存非常重要,尤其是在您希望在那里通常存在值的應用程序中。 我傾向于根據需要頻繁查詢數據庫,以避免不必要的方法參數或本地緩存 。 一切使代碼盡可能簡單。 但是,這種方法僅在數據庫層上的緩存正常工作時才有效。 與Hibernate相似,在EhCache中啟用JMX監視是一個兩步過程。 首先,您需要在MBeanServer
公開提供的MBean
:
@Bean(initMethod = "init", destroyMethod = "dispose")
def managementService = new ManagementService(ehCacheManager(), platformMBeanServer(), true, true, true, true, true)@Bean def platformMBeanServer() = ManagementFactory.getPlatformMBeanServerdef ehCacheManager() = ehCacheManagerFactoryBean.getObject@Bean def ehCacheManagerFactoryBean = {val ehCacheManagerFactoryBean = new EhCacheManagerFactoryBeanehCacheManagerFactoryBean.setShared(true)ehCacheManagerFactoryBean.setCacheManagerName("spring-pitfalls")ehCacheManagerFactoryBean
}
請注意,我明確設置了CacheManager
名稱。 這不是必需的,但是此名稱用作Mbean名稱的一部分,并且默認名稱包含hashCode
值,這不是很好。 最后一點是啟用基于緩存的統計信息:
<cache name="org.hibernate.cache.StandardQueryCache"maxElementsInMemory="10000"eternal="false"timeToIdleSeconds="3600"timeToLiveSeconds="600"overflowToDisk="false"memoryStoreEvictionPolicy="LRU"statistics="true"
/>
現在,我們可以愉快地分別監視每個緩存的各種緩存特征:
如我們所見,緩存未命中的百分比增加了。 從來沒有一件好事。 如果我們不啟用緩存統計信息,那么啟用JMX仍然是一個好主意,因為我們免費獲得了許多管理操作,包括刷新和清除緩存(在調試和測試過程中很有用)。
石英調度器
以我的拙見, Quartz Scheduler是一個被低估的庫,但是我將自己撰寫一篇有關它的文章。 這次,我們將僅學習如何通過JMX對其進行監視。 幸運的是,它就像添加一樣簡單:
org.quartz.scheduler.jmx.export=true
到quartz.properties
文件。 Quartz中對JMX的支持可能會稍微擴大一點,但是仍然可以查詢例如當前正在運行的作業。 順便說一下,新的主要版本的Quartz(2.x)帶來了非常好的DSL類似的調度支持:
val job = newJob(classOf[MyJob])
val trigger = newTrigger().withSchedule(repeatSecondlyForever()).startAt(futureDate(30, SECOND))
scheduler.scheduleJob(job.build(), trigger.build())
Apache Commons DBCP
Apache Commons DBCP是我遇到的最合理的JDBC池庫。 還有c3p0 ,但似乎不再積極開發了。 Tomcat JDBC連接池看起來很有前途,但是由于它捆綁在Tomcat中,因此您的JDBC驅動程序不能再打包在WAR中。
DBCP的唯一問題是它不支持JMX。 完全沒有(請參見此兩年半的舊版 )。 幸運的是,這很容易解決。 此外,我們還將學習如何使用Spring內置的JMX支持。
看起來標準的BasicDataSource
擁有我們所需的全部,我們要做的就是通過JMX公開現有的指標。 使用Spring時,它簡直就是簡單–只需@ManagedAttribute
子類,然后在所需的屬性上添加@ManagedAttribute
批注:
@ManagedResource
class ManagedBasicDataSource extends BasicDataSource {@ManagedAttribute override def getNumActive = super.getNumActive@ManagedAttribute override def getNumIdle = super.getNumIdle@ManagedAttribute def getNumOpen = getNumActive + getNumIdle@ManagedAttribute override def getMaxActive: Int= super.getMaxActive@ManagedAttribute override def setMaxActive(maxActive: Int) {super.setMaxActive(maxActive)}@ManagedAttribute override def getMaxIdle = super.getMaxIdle@ManagedAttribute override def setMaxIdle(maxIdle: Int) {super.setMaxIdle(maxIdle)}@ManagedAttribute override def getMinIdle = super.getMinIdle@ManagedAttribute override def setMinIdle(minIdle: Int) {super.setMinIdle(minIdle)}@ManagedAttribute override def getMaxWait = super.getMaxWait@ManagedAttribute override def setMaxWait(maxWait: Long) {super.setMaxWait(maxWait)}@ManagedAttribute override def getUrl = super.getUrl@ManagedAttribute override def getUsername = super.getUsername
}
以下是一些在負載測試期間瘋狂的數據源指標:
Spring框架本身對JMX的支持非常簡單。 如您所見,公開任意屬性或操作只是添加注釋的問題。 您只需要記住有關使用XML或Java啟用JMX支持的方法(另請參見: SPR-8943:等效于<context:mbean-export />的@Configuration ):
<context:mbean-export/>
要么:
@Bean def annotationMBeanExporter() = new AnnotationMBeanExporter()
這篇文章并不特別令人興奮。 但是,對JMX指標的了解將使我們能夠立即編寫簡單而精致的儀表板。 敬請關注!
參考: Java和社區博客上的JCG合作伙伴 Tomasz Nurkiewicz提供了在Hibernate,EhCache,Quartz,DBPC和Spring中啟用JMX的信息 。
相關文章 :
- 使用Spring將POJO公開為JMX MBean
- 休眠陷阱
- DataNucleus 3.0與Hibernate 3.5
- Spring 3.1和Hibernate的持久層
- 使用Spring和Java泛型簡化數據訪問層
- Spring 3.1和JPA的持久層
翻譯自: https://www.javacodegeeks.com/2012/01/enabling-jmx-in-hibernate-ehcache-qurtz.html