shiro使用ehcache实现集群同步和session复制

一般情况下WEB应用集群的会话复制都是通过容器实现的,shiro权限框架中可以定义SessionDAO直接将session持久化到缓存中,这样只需要对缓存做集群就可以代替session的复制。 

实现思路 
1、用SessionDAO将session保存到ehcache缓存 
2、配置ehcache的jgroups集群复制,如果集群服务器比较多,可升级到缓存服务器 

思路很简单,但实现过程遇到不少问题,现在把过程及配置文件记录下来,避免忘记。 

第一步将SessionDAO保存到ehcache缓存,这个步骤很简单,也没出什么问题,按照网上的例子很容易,下面是配置文件主要片段: 

Java代码 

 收藏代码

  1. <!-- 主要是为了注入SessionDAO -->  
  2.  <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">  
  3.   <property name="sessionDAO" ref="sessionDAO"/>  
  4.  </bean>  
  5. <!-- SessionDAO用shiro提供的默认实现 -->  
  6.  <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">   
  7.        <!-- <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/> -->  
  8.         <property name="cacheManager" ref="shiroCacheManager" />  
  9. </bean>  
  10. <!-- 为了实现自己的用户权限 -->  
  11.  <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  12.      <property name="realm" ref="userRealm"/>  
  13.      <property name="sessionManager" ref="sessionManager"/>  
  14.      <!-- By default the servlet container sessions will be used.  Uncomment this line  
  15.           to use shiro's native sessions (see the JavaDoc for more): -->  
  16.      <!-- <property name="sessionMode" value="native"/> -->  
  17.  </bean>  
  18. <!-- 自定义的用户权限,这里也需要用缓存,避免从数据库加载权限 -->  
  19.  <bean id="userRealm" class="cn.ys.security.UserRealm">  
  20.   <property name="cacheManager" ref="shiroCacheManager"/>  
  21.   <property name="userService" ref="securityService" />  
  22.   <property name="credentialsMatcher" ref="credentialsMatcher"></property>  
  23.  </bean>  
  24. <!-- 与spring ehcache集成 -->  
  25. <bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">  
  26.         <property name="cacheManager" ref="ehcache"/>  
  27.         <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>  
  28.     </bean>  


第二步遇到很多问题,网上资料比较少,对jgroups又不熟,下面是配置文件及我遇到的问题: 
ehcache.xml 
 

Java代码 

 收藏代码

  1. <!-- 缓存同步jgroup配置 -->  
  2.  <cacheManagerPeerProviderFactory  
  3.  class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"  
  4.  properties="file=jgroups_tcp.xml"  />   
  5.  <diskStore path="java.io.tmpdir/ehcache"/>  
  6.    <defaultCache    
  7.             maxElementsInMemory="10000"    
  8.             eternal="false"    
  9.             timeToIdleSeconds="120"    
  10.             timeToLiveSeconds="120"    
  11.             overflowToDisk="true"    
  12.             maxElementsOnDisk="10000000"    
  13.             diskPersistent="false"    
  14.             diskExpiryThreadIntervalSeconds="120"    
  15.             memoryStoreEvictionPolicy="LRU"    
  16.             />   
  17.     <cache name="shiro-activeSessionCache"  
  18.            maxElementsInMemory="1000"  
  19.            overflowToDisk="true"  
  20.            timeToLiveSeconds="0"  
  21.            timeToIdleSeconds="0"  
  22.            diskPersistent="true"  
  23.            diskExpiryThreadIntervalSeconds="600">  
  24.    <cacheEventListenerFactory  
  25.           class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"  
  26.           properties="replicateAsynchronously=true, replicatePuts=true,  
  27.           replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true" />  
  28.     </cache>  
  29.     <cache name="cn.ys.security.UserRealm.authorizationCache"  
  30.            maxElementsInMemory="1000"  
  31.            eternal="true"  
  32.            overflowToDisk="true">  
  33.    <cacheEventListenerFactory  
  34.           class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"  
  35.           properties="replicateAsynchronously=true, replicatePuts=true,  
  36.           replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true" />  
  37.  </cache>  
  38.   
  39.     <cache name="org.apache.shiro.realm.text.PropertiesRealm-0-accounts"  
  40.            maxElementsInMemory="1000"  
  41.            eternal="true"  
  42.            overflowToDisk="true">  
  43.    <cacheEventListenerFactory  
  44.           class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"  
  45.           properties="replicateAsynchronously=true, replicatePuts=true,  
  46.           replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true" />  
  47.  </cache>  
  48.   
  49. jgroups_tcp.xml  
  50.  <config>  
  51.      <TCP bind_port="7800" bind_addr="localhost"  
  52.   loopback="false"  
  53.          recv_buf_size="${tcp.recv_buf_size:20M}"  
  54.          send_buf_size="${tcp.send_buf_size:1M}"  
  55.          discard_incompatible_packets="true"  
  56.          max_bundle_size="2M"  
  57.          max_bundle_timeout="30"  
  58.          enable_bundling="true"  
  59.          use_send_queues="true"  
  60.          sock_conn_timeout="300"  
  61.   
  62.          timer_type="new"  
  63.          timer.min_threads="4"  
  64.          timer.max_threads="10"  
  65.          timer.keep_alive_time="3000"  
  66.          timer.queue_max_size="500"  
  67.            
  68.          thread_pool.enabled="true"  
  69.          thread_pool.min_threads="1"  
  70.          thread_pool.max_threads="10"  
  71.          thread_pool.keep_alive_time="5000"  
  72.          thread_pool.queue_enabled="false"  
  73.          thread_pool.queue_max_size="100"  
  74.          thread_pool.rejection_policy="discard"  
  75.   
  76.          oob_thread_pool.enabled="true"  
  77.          oob_thread_pool.min_threads="1"  
  78.          oob_thread_pool.max_threads="8"  
  79.          oob_thread_pool.keep_alive_time="5000"  
  80.          oob_thread_pool.queue_enabled="false"  
  81.          oob_thread_pool.queue_max_size="100"  
  82.          oob_thread_pool.rejection_policy="discard"      
  83.      />  
  84.      <TCPPING timeout="3000"  
  85.               initial_hosts="localhost[7800]"  
  86.               port_range="5"  
  87.               num_initial_members="5"/>  
  88.     <MERGE2  min_interval="10000"  
  89.              max_interval="30000"/>  
  90.     <FD_SOCK/>  
  91.     <FD timeout="3000" max_tries="3" />  
  92.     <VERIFY_SUSPECT timeout="1500"  />  
  93.     <BARRIER />  
  94.     <pbcast.NAKACK use_mcast_xmit="false"  
  95.                     retransmit_timeout="300,600,1200,2400,4800"  
  96.                     discard_delivered_msgs="true"/>  
  97.     <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000" max_bytes="400000"/>  
  98.     <pbcast.GMS print_local_addr="true" join_timeout="5000" view_bundling="true"/>  
  99.  </config>  



在网上查找的例子jgroups版本可能比较老,ehcache中的例子也一样,有些属性新的jgroups已经不认了,如start_port已经改成了bind_port,另外新版本jgroups增加了bind_addr,这样就可以直接指定ip地址绑定了,不需要在jvm上增加ipv4参数。 
配置jgroups的几个需要理解的地方 
1、jgroups的TCP的端口是自动分配自动发现的,同一台服务器上的多个实例不需要都配置到initial_hosts中,一个IP在initial_hosts中只需要定义一次,端口与bind_port保持一致 
2、port_range是用于端口自动分配和自动发现用的,例如bind_port值为7800,当同服务上的第一个实例启动是使用7800端口,第二个实现启动时使用的是7801,最多只到7804 
3、max_bundle_size不要太小,例子上该值只有64K,结果有时会现在无法复制的情况 
4、当实例关闭再启动时,jgroups会认为是另一个host,原来的host如果不设置超时会一直存在,所以要注意设置keep_alive_time

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值