Spring之Hibernate+JBoss Treecache实现Hibernate集群

GD Star Rating
loading...

本文版权归本人所有,任何转载请标明出处

Hibernate作为一个ORM框架可以说已经做到了极致,但是绝大多数情况下Hibernate都被应用于单容器环境中,以至于互联网上能够找到的在集群环境中使用的参考少之又少,和Spring整合的就更别说了。实际上,Hibernate可以使用JBoss的Treecache作为二级缓存以支持分布式集群

本文将使用Spring 3.0.2框架集成Hibernate 3.5.2,并将Treecache 3.2.5作为二级缓存

Spring配置

  1. <context:annotation-config />
  2.  
  3. <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  4.         ...
  5. <property name="hibernateProperties">
  6.             <value>
  7.                 hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
  8.                 hibernate.cache.use_second_level_cache=true
  9.                 hibernate.show_sql=true
  10.                 hibernate.cache.region.factory_class=org.hibernate.cache.jbc2.SharedJBossCacheRegionFactory
  11.                 hibernate.cache.use_query_cache=true
  12.                 hibernate.hbm2ddl.auto=update
  13.             </value>
  14.         </property>
  15.     </bean>
<context:annotation-config />

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        ...
<property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
                hibernate.cache.use_second_level_cache=true
                hibernate.show_sql=true
                hibernate.cache.region.factory_class=org.hibernate.cache.jbc2.SharedJBossCacheRegionFactory
                hibernate.cache.use_query_cache=true
                hibernate.hbm2ddl.auto=update
            </value>
        </property>
    </bean>

其中第1行打开Spring的annotation支持,即使用annotation替代之前版本中的大量XML配置(貌似这个选项在Spring 2.5中就被引入,但不知道是因为大家懒还是配置文件的基本内容都是在互联网上Ctrl C+V 2.5之前的代码,反正互联网上一搜Spring的配置满眼都是XML片段);第8行打开二级缓存;第10行选择Treecache作为缓存region工厂的实现类

对于需要被缓存的实体,只需要在类定义上加上@Cache注释,如:

  1. @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
  2. public class MyModel {
  3.     ...
  4. }
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
public class MyModel {
    ...
}

由于Treecache只支持只读缓存和事务缓存,因此这里usage只能设为READ_ONLY或TRANSACTIONAL,但需要注意的是设为只读缓存时不能打开Hibernate的query cache

最后是Treecache的配置,如果配置文件名是treecache.xml且在classpath中则无需指定,否则需要在上述Spring配置的代码段中指定。至于具体配置内容,可参考Treecache源代码中的sample,调优方式可参考Treecache文档,这里给一个sample

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.2">
  3.  
  4.    <!-- Configure the TransactionManager -->
  5. <transaction transactionManagerLookupClass="org.jboss.cache.transaction.GenericTransactionManagerLookup"/>
  6.  
  7.    <clustering mode="replication">
  8.       <!--
  9.       timeout: The max amount of time (in milliseconds) we wait until the
  10.             state (i.e. the contents of the cache) are retrieved from
  11.             existing members in a clustered environment
  12.      -->
  13.       <stateRetrieval timeout="20000"/>
  14.  
  15.       <!-- JGroups protocol stack properties. -->
  16.       <jgroupsConfig>
  17.          <udp discard_incompatible_packets="true" enable_bundling="true" enable_diagnostics="false" ip_ttl="2"
  18.              loopback="false" max_bundle_size="64000" max_bundle_timeout="30" mcast_addr="224.12.12.12"
  19.              mcast_port="45588" mcast_recv_buf_size="100000000" mcast_send_buf_size="640000"
  20.              oob_thread_pool.enabled="true" oob_thread_pool.keep_alive_time="10000" oob_thread_pool.max_threads="20"
  21.              oob_thread_pool.min_threads="8" oob_thread_pool.queue_enabled="false" oob_thread_pool.queue_max_size="10"
  22.              oob_thread_pool.rejection_policy="Run" thread_naming_pattern="pl" thread_pool.enabled="true"
  23.              thread_pool.keep_alive_time="10000" thread_pool.max_threads="15" thread_pool.min_threads="8"
  24.              thread_pool.queue_enabled="true" thread_pool.queue_max_size="100000"
  25.              thread_pool.rejection_policy="Discard"
  26.              tos="8" ucast_recv_buf_size="20000000" ucast_send_buf_size="640000" use_concurrent_stack="true"
  27.              use_incoming_packet_handler="true"/>
  28. <ping num_initial_members="3" timeout="2000"/>
  29.          <merge2 max_interval="30000" min_interval="10000"/>
  30.          <fd_SOCK/>
  31.          <fd max_tries="5" shun="true" timeout="10000"/>
  32.          <verify_SUSPECT timeout="1500"/>
  33. <pbcast.NAKACK discard_delivered_msgs="true" gc_lag="0" retransmit_timeout="300,600,1200,2400,4800"
  34.                        use_mcast_xmit="true"/>
  35.          <unicast timeout="300,600,1200,2400,3600"/>
  36. <pbcast.STABLE desired_avg_gossip="50000" max_bytes="400000" stability_delay="1000"/>
  37. <pbcast.GMS join_timeout="5000" print_local_addr="true" shun="false" view_ack_collection_timeout="5000"
  38.                     view_bundling="true"/>
  39.          <fc max_credits="500000" min_threshold="0.2"/>
  40.          <frag2 frag_size="60000"/>
  41. <pbcast.STREAMING_STATE_TRANSFER/>
  42. <pbcast.FLUSH timeout="0"/>
  43.       </jgroupsConfig>
  44.  
  45.       <async />
  46.       <!-- Alternatively, to use sync replication, comment out the element above and uncomment the element below.  -->
  47.       <!-- <sync /> -->
  48.  
  49.    </clustering>
  50. </jbosscache>
<?xml version="1.0" encoding="UTF-8"?>
<jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.2">

   <!-- Configure the TransactionManager -->
<transaction transactionManagerLookupClass="org.jboss.cache.transaction.GenericTransactionManagerLookup"/>

   <clustering mode="replication">
      <!--
       timeout: The max amount of time (in milliseconds) we wait until the
             state (i.e. the contents of the cache) are retrieved from
             existing members in a clustered environment
      -->
      <stateRetrieval timeout="20000"/>

      <!-- JGroups protocol stack properties. -->
      <jgroupsConfig>
         <udp discard_incompatible_packets="true" enable_bundling="true" enable_diagnostics="false" ip_ttl="2"
              loopback="false" max_bundle_size="64000" max_bundle_timeout="30" mcast_addr="224.12.12.12"
              mcast_port="45588" mcast_recv_buf_size="100000000" mcast_send_buf_size="640000"
              oob_thread_pool.enabled="true" oob_thread_pool.keep_alive_time="10000" oob_thread_pool.max_threads="20"
              oob_thread_pool.min_threads="8" oob_thread_pool.queue_enabled="false" oob_thread_pool.queue_max_size="10"
              oob_thread_pool.rejection_policy="Run" thread_naming_pattern="pl" thread_pool.enabled="true"
              thread_pool.keep_alive_time="10000" thread_pool.max_threads="15" thread_pool.min_threads="8"
              thread_pool.queue_enabled="true" thread_pool.queue_max_size="100000"
              thread_pool.rejection_policy="Discard"
              tos="8" ucast_recv_buf_size="20000000" ucast_send_buf_size="640000" use_concurrent_stack="true"
              use_incoming_packet_handler="true"/>
<ping num_initial_members="3" timeout="2000"/>
         <merge2 max_interval="30000" min_interval="10000"/>
         <fd_SOCK/>
         <fd max_tries="5" shun="true" timeout="10000"/>
         <verify_SUSPECT timeout="1500"/>
<pbcast.NAKACK discard_delivered_msgs="true" gc_lag="0" retransmit_timeout="300,600,1200,2400,4800"
                        use_mcast_xmit="true"/>
         <unicast timeout="300,600,1200,2400,3600"/>
<pbcast.STABLE desired_avg_gossip="50000" max_bytes="400000" stability_delay="1000"/>
<pbcast.GMS join_timeout="5000" print_local_addr="true" shun="false" view_ack_collection_timeout="5000"
                     view_bundling="true"/>
         <fc max_credits="500000" min_threshold="0.2"/>
         <frag2 frag_size="60000"/>
<pbcast.STREAMING_STATE_TRANSFER/>
<pbcast.FLUSH timeout="0"/>
      </jgroupsConfig>

      <async />
      <!-- Alternatively, to use sync replication, comment out the element above and uncomment the element below.  -->
      <!-- <sync /> -->

   </clustering>
</jbosscache>

需要注意的是第7行,集群mode。Treecache的分布式同步有两种模式:replication和invalidation。这两者的区别是:对于replication,每一个节点(缓存)中的对象改变时,该节点会将新对象通过多播的方式告知多播组中的其它节点,其它节点自行更新;而对于invalidation模式,发生改变的节点只通知其它节点某对象已发生改变,其它节点直接将自己缓存中的该对象标记为invalid,待下次需要使用时通过数据库更新该对象。这样一解释就能发现取舍的策略了:若网络比数据库金贵,选择invalidation,标记自己的对象,让数据库忙活去吧;若数据库金贵,使用replication多播对象

另外,由于Treecache使用了基于多播协议的jgroup库作为底层通信框架,在配置Treecache集群时不需要了解多播组中其他节点IP,只需要把第19行的多播地址(必须是D类地址)配成一个的就行了,jgroup会自行发现多播组中的其它节点

世界杯大酬宾:如何使用JMX监控Treecache的状态

启动容器;打开任意JMX客户端,如jconsole;在进程列表中选择容器的java进程并连接;选择“mbean”标签,找到“jboss.cache”节点,如下图


在这个节点下可以看到所有Treecache通过JMX暴露的属性,包括命中率、缓存对象等

原创内容,转载请注明: 转载自拈花微笑

本文链接地址: Spring之Hibernate+JBoss Treecache实现Hibernate集群

685

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code lang=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" extra="">

:wink: :-| :-x :twisted: :) 8-O :( :roll: :-P :oops: :-o :mrgreen: :lol: :idea: :-D :evil: :cry: 8) :arrow: :-? :?: :!:

使用新浪微博登陆

无觅相关文章插件,快速提升流量