在Tomcat中使用Spring通过JMX公开Hibernate(缓存)统计信息 [英] Exposing Hibernate (cache) statistics through JMX with Spring in Tomcat

查看:94
本文介绍了在Tomcat中使用Spring通过JMX公开Hibernate(缓存)统计信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

收集Hibernate / Ehcache统计信息并在基于Spring的设置中通过JMX公开它们似乎很容易。互联网有很多资源可以帮助 http://snippets.dzone.com/posts/show/11159



然而,所有这些文章都假设您正在与某种Hibernate会话工厂合作。我不是 - 我的实体是JPA注释,我使用 javax.persistence.EntityManager
如果我正在部署到Java EE容器,那么我可能已经能够通过JNDI获取Hibernate会话工厂,如此处所述 http://internna.blogspot.com/2007/08/hibernate-statistics-in-enterprise-5.html ,但我在Tomcat ...



如何解决这个问题?我还没有拿出一个解决方案。



如果我有一个引用Ehcache CacheManager 我可以尝试如下:

 < context:mbean-server /> 
< bean class =net.sf.ehcache.management.ManagementServiceinit-method =init>
< constructor-arg ref =.. myCacheManager ../>
< constructor-arg ref =mbeanServer/>
< constructor-arg value =true/>
< constructor-arg value =true/>
< constructor-arg value =true/>
< constructor-arg value =true/>
< / bean>

由于缓存管理器是由Hibernate创建的(即它不是Spring bean),它将不起作用。我尝试用

 < constructor-arg>< bean id =cacheManagerclass =net.sf替换那个ref .ehcache.CacheManagerfactory-method =getInstance/>< / constructor-arg> 

希望我能以某种方式捕捉正确的实例。因为这实际上会创建一个新的缓存管理器实例,所以无法工作。

解决方案

我最终编写了下面的类



HibernateStatisticsJmxRegistration
$ b

  import javax.management .JMException; 
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.persistence.EntityManagerFactory;

import org.hibernate.SessionFactory;
import org.hibernate.ejb.HibernateEntityManagerFactory;
import org.hibernate.jmx.StatisticsService;
import org.springframework.beans.factory.annotation.Autowired;

/ **
*提供代码使用JMX MBean服务器注册Hibernate的统计信息bean。假定
* MBeanServer和EntityManagerFactory都可用作Spring管理的bean。请注意,注册此类时
*可以收集统计信息,即使之前为
*禁用。
*< p>
*可能一度过时< a href =https://hibernate.onjira.com/browse/HHH-6034> HHH-6034< / a>是
*实施。即使不是令人困惑的情况,同时弃用的
* {@link StatisticsService}也应该清楚。
* /
@SuppressWarnings({deprecation,javadoc})
public class HibernateStatisticsJmxRegistration {
$ b $ @Autowired
private EntityManagerFactory entityManagerFactory;

@Autowired
private MBeanServer mbeanServer;

private ObjectName objectName;

private String jmxObjectName =org.hibernate:name = HibernateStatistics;

/ **
*注册包装Hibernate会话工厂的统计MBean。该Bean在{@link HibernateStatisticsJmxRegistration#getJmxObjectName()}提供的名称下注册
*。
*
* @ throws JMException如果有任何失败..
* @see HibernateStatisticsJmxRegistration#unregister()
* /
public void register()throws JMException {
final SessionFactory sessionFactory =((HibernateEntityManagerFactory)entityManagerFactory).getSessionFactory();

objectName = new ObjectName(jmxObjectName);

最终StatisticsService statsMBean = new StatisticsService();
statsMBean.setSessionFactory(sessionFactory);
statsMBean.setStatisticsEnabled(true);
mbeanServer.registerMBean(statsMBean,objectName);
}

/ **
*注销已注册的MBean。
*
* @throws JMException如果注销失败
* @see HibernateStatisticsJmxRegistration#register()
* /
public void unregister()throws JMException {
mbeanServer.unregisterMBean(objectName);
}

/ **
*覆盖默认的JMX对象名称。很明显,您需要在
*注册之前调用此方法才能起作用。该字符串必须符合
* {@link ObjectName}中描述的规则。建议使用{@code< domain>:name =< name>}。
*
* @param jmxObjectName注册期间使用的名称
* /
public void setJmxObjectName(String jmxObjectName){
this.jmxObjectName = jmxObjectName;


Spring配置 p>

 <! - 为各种缓存设置Ehcache管理器(offer facade,images)。 - > 
< bean id =ehCacheManagerclass =org.springframework.cache.ehcache.EhCacheManagerFactoryBean>
< property name =configLocationvalue =classpath:ehcache.xml/>
< / bean>
< ehcache:annotation-driven cache-manager =ehCacheManager/>

<! - 通过JMX公开缓存统计信息。 - >
< context:mbean-server />
< bean class =net.sf.ehcache.management.ManagementServiceinit-method =init>
< constructor-arg ref =ehCacheManager/>
< constructor-arg ref =mbeanServer/>
< constructor-arg value =true/>
< constructor-arg value =true/>
< constructor-arg value =true/>
< constructor-arg value =true/>
< / bean>
< bean class =HibernateStatisticsJmxRegistration
init-method =registerdestroy-method =unregister/>


Collecting Hibernate/Ehcache statistics and exposing them through JMX in Spring-based setups seems easy. The Internet has lots of resources that help e.g. http://snippets.dzone.com/posts/show/11159

However, all those articles assume one is working with a Hibernate session factory of some sort. I'm not - my entities are JPA annotated and I use a javax.persistence.EntityManager. If I were deploying to a Java EE container I might have been able to obtain a Hibernate session factory through JNDI as described here http://internna.blogspot.com/2007/08/hibernate-statistics-in-enterprise-5.html but I'm on Tomcat...

How to go about this? I haven't come up with a solution yet.

If I had a reference to the Ehcache CacheManager I could try something like:

<context:mbean-server />
<bean class="net.sf.ehcache.management.ManagementService" init-method="init">
  <constructor-arg ref="..myCacheManager.."/>
  <constructor-arg ref="mbeanServer"/>
  <constructor-arg value="true"/>
  <constructor-arg value="true"/>
  <constructor-arg value="true"/>
  <constructor-arg value="true"/>
</bean>

Since the cache manager is created by Hibernate (i.e. it's not a Spring bean) it won't work. I tried replacing that ref with

<constructor-arg><bean id="cacheManager" class="net.sf.ehcache.CacheManager" factory-method="getInstance"/></constructor-arg>

hoping I'd somehow catch the right instance. Won't work either as this would in fact create a new cache manager instance.

解决方案

I ended up writing the following class

HibernateStatisticsJmxRegistration

import javax.management.JMException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.persistence.EntityManagerFactory;

import org.hibernate.SessionFactory;
import org.hibernate.ejb.HibernateEntityManagerFactory;
import org.hibernate.jmx.StatisticsService;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Provides code to register Hibernate's statistics bean with a JMX MBean server. Assumes that both
 * the MBeanServer and the EntityManagerFactory are available as Spring-managed beans. Note that
 * while registering this class enables the collection of statistics even if that was previously
 * disabled.
 * <p>
 * May become obsolete once <a href="https://hibernate.onjira.com/browse/HHH-6034">HHH-6034</a> is
 * implemented. Even if not the confusing situation abround the meanwhile deprecated
 * {@link StatisticsService} should be clear then.
 */
@SuppressWarnings({"deprecation", "javadoc" })
public class HibernateStatisticsJmxRegistration {

  @Autowired
  private EntityManagerFactory entityManagerFactory;

  @Autowired
  private MBeanServer mbeanServer;

  private ObjectName objectName;

  private String jmxObjectName = "org.hibernate:name=HibernateStatistics";

  /**
   * Registers the statistics MBean that wraps a Hibernate session factory. The bean is registered
   * under the name provided by {@link HibernateStatisticsJmxRegistration#getJmxObjectName()}.
   *
   * @throws JMException if anything fails..
   * @see HibernateStatisticsJmxRegistration#unregister()
   */
  public void register() throws JMException {
    final SessionFactory sessionFactory = ((HibernateEntityManagerFactory) entityManagerFactory).getSessionFactory();

    objectName = new ObjectName(jmxObjectName);

    final StatisticsService statsMBean = new StatisticsService();
    statsMBean.setSessionFactory(sessionFactory);
    statsMBean.setStatisticsEnabled(true);
    mbeanServer.registerMBean(statsMBean, objectName);
  }

  /**
   * Unregisters the MBean that was registered.
   *
   * @throws JMException if the de-registration fails
   * @see HibernateStatisticsJmxRegistration#register()
   */
  public void unregister() throws JMException {
    mbeanServer.unregisterMBean(objectName);
  }

  /**
   * Override the default JMX object name. Obviously you need to call this method before
   * registration for it to have any effect. The string must comply to the rules described in
   * {@link ObjectName}. Suggested is {@code <domain>:name=<name>}.
   *
   * @param jmxObjectName the name to use during registration
   */
  public void setJmxObjectName(String jmxObjectName) {
    this.jmxObjectName = jmxObjectName;
  }
}

Spring configuration

<!-- Setting up Ehcache manager for various caches (offer facade, images). -->
<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
  <property name="configLocation" value="classpath:ehcache.xml" />
</bean>  
<ehcache:annotation-driven cache-manager="ehCacheManager" />

<!-- Exposing cache statistics through JMX. -->
<context:mbean-server />
<bean class="net.sf.ehcache.management.ManagementService" init-method="init">
  <constructor-arg ref="ehCacheManager"/>
  <constructor-arg ref="mbeanServer"/>
  <constructor-arg value="true"/>
  <constructor-arg value="true"/>
  <constructor-arg value="true"/>
  <constructor-arg value="true"/>
</bean>    
<bean class="HibernateStatisticsJmxRegistration"
      init-method="register" destroy-method="unregister" />

这篇关于在Tomcat中使用Spring通过JMX公开Hibernate(缓存)统计信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆