oscache 集群和数据同步

Java代码   收藏代码
  1. cache.event.listeners=com.test.JavaGroupsBroadcastingListenerImpl  
  2. cache.cluster.properties=UDP(mcast_addr=231.12.21.132;mcast_port=45566;ip_ttl=32;\  
  3. mcast_send_buf_size=150000;mcast_recv_buf_size=80000):\  
  4. PING(timeout=2000;num_initial_members=3):\  
  5. MERGE2(min_interval=5000;max_interval=10000):\  
  6. FD_SOCK:VERIFY_SUSPECT(timeout=1500):\  
  7. pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800;max_xmit_size=8192):\  
  8. UNICAST(timeout=300,600,1200,2400):\  
  9. pbcast.STABLE(desired_avg_gossip=20000):\  
  10. FRAG(frag_size=8096;down_thread=false;up_thread=false):\  
  11. pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_local_addr=true)  
  12. cache.cluster.multicast.ip=231.12.21.132  

 oscache 集群同步数据需要使用到JavaGroupsBroadcastingListener,但是JavaGroupsBroadcastingListener 具体没有实现同步的功能,JavaGroupsBroadcastingListener:

Java代码   收藏代码
  1. public void handleNotification(Serializable serializable) {  
  2.        if (!(serializable instanceof ClusterNotification)) {  
  3.            log.error("An unknown cluster notification message received (class=" + serializable.getClass().getName() + "). Notification ignored.");  
  4.   
  5.            return;  
  6.        }  
  7.   
  8.        handleClusterNotification((ClusterNotification) serializable);  
  9.    }  

 handleNotification该方法调用 handleClusterNotification((ClusterNotification) serializable)后,进入AbstractBoardcasting类,改方法只执行刷新当前缓存的内容,对集群数据同步没有实现。

Java代码   收藏代码
  1. /* 
  2.  * Copyright (c) 2002-2003 by OpenSymphony 
  3.  * All rights reserved. 
  4.  */  
  5. package com.opensymphony.oscache.plugins.clustersupport;  
  6.   
  7. import com.opensymphony.oscache.base.*;  
  8. import com.opensymphony.oscache.base.events.*;  
  9.   
  10. import org.apache.commons.logging.Log;  
  11. import org.apache.commons.logging.LogFactory;  
  12.   
  13. import java.util.Date;  
  14.   
  15. /** 
  16.  * Implementation of a CacheEntryEventListener. It broadcasts the flush events 
  17.  * across a cluster to other listening caches. Note that this listener cannot 
  18.  * be used in conjection with session caches. 
  19.  * 
  20.  * @version        $Revision: 254 $ 
  21.  * @author <a href="&#109;a&#105;&#108;&#116;&#111;:chris&#64;swebtec.&#99;&#111;&#109;">Chris Miller</a> 
  22.  */  
  23. public abstract class AbstractBroadcastingListener implements CacheEntryEventListener, LifecycleAware {  
  24.     private final static Log log = LogFactory.getLog(AbstractBroadcastingListener.class);  
  25.   
  26.     /** 
  27.      * The name to use for the origin of cluster events. Using this ensures 
  28.      * events are not fired recursively back over the cluster. 
  29.      */  
  30.     protected static final String CLUSTER_ORIGIN = "CLUSTER";  
  31.     protected Cache cache = null;  
  32.   
  33.     public AbstractBroadcastingListener() {  
  34.         if (log.isInfoEnabled()) {  
  35.             log.info("AbstractBroadcastingListener registered");  
  36.         }  
  37.     }  
  38.   
  39.     /** 
  40.      * Event fired when an entry is flushed from the cache. This broadcasts 
  41.      * the flush message to any listening nodes on the network. 
  42.      */  
  43.     public void cacheEntryFlushed(CacheEntryEvent event) {  
  44.         if (!Cache.NESTED_EVENT.equals(event.getOrigin()) && !CLUSTER_ORIGIN.equals(event.getOrigin())) {  
  45.             if (log.isDebugEnabled()) {  
  46.                 log.debug("cacheEntryFlushed called (" + event + ")");  
  47.             }  
  48.   
  49.             sendNotification(new ClusterNotification(ClusterNotification.FLUSH_KEY, event.getKey()));  
  50.         }  
  51.     }  
  52.   
  53.     /** 
  54.      * Event fired when an entry is removed from the cache. This broadcasts 
  55.      * the remove method to any listening nodes on the network, as long as 
  56.      * this event wasn't from a broadcast in the first place. 
  57.      */  
  58.     public void cacheGroupFlushed(CacheGroupEvent event) {  
  59.         if (!Cache.NESTED_EVENT.equals(event.getOrigin()) && !CLUSTER_ORIGIN.equals(event.getOrigin())) {  
  60.             if (log.isDebugEnabled()) {  
  61.                 log.debug("cacheGroupFushed called (" + event + ")");  
  62.             }  
  63.   
  64.             sendNotification(new ClusterNotification(ClusterNotification.FLUSH_GROUP, event.getGroup()));  
  65.         }  
  66.     }  
  67.   
  68.     public void cachePatternFlushed(CachePatternEvent event) {  
  69.         if (!Cache.NESTED_EVENT.equals(event.getOrigin()) && !CLUSTER_ORIGIN.equals(event.getOrigin())) {  
  70.             if (log.isDebugEnabled()) {  
  71.                 log.debug("cachePatternFushed called (" + event + ")");  
  72.             }  
  73.   
  74.             sendNotification(new ClusterNotification(ClusterNotification.FLUSH_PATTERN, event.getPattern()));  
  75.         }  
  76.     }  
  77.   
  78.     public void cacheFlushed(CachewideEvent event) {  
  79.         if (!Cache.NESTED_EVENT.equals(event.getOrigin()) && !CLUSTER_ORIGIN.equals(event.getOrigin())) {  
  80.             if (log.isDebugEnabled()) {  
  81.                 log.debug("cacheFushed called (" + event + ")");  
  82.             }  
  83.   
  84.             sendNotification(new ClusterNotification(ClusterNotification.FLUSH_CACHE, event.getDate()));  
  85.         }  
  86.     }  
  87.   
  88.     // --------------------------------------------------------  
  89.     // The remaining events are of no interest to this listener  
  90.     // --------------------------------------------------------  
  91.     public void cacheEntryAdded(CacheEntryEvent event) {  
  92.     }  
  93.   
  94.     public void cacheEntryRemoved(CacheEntryEvent event) {  
  95.     }  
  96.   
  97.     public void cacheEntryUpdated(CacheEntryEvent event) {  
  98.     }  
  99.   
  100.     public void cacheGroupAdded(CacheGroupEvent event) {  
  101.     }  
  102.   
  103.     public void cacheGroupEntryAdded(CacheGroupEvent event) {  
  104.     }  
  105.   
  106.     public void cacheGroupEntryRemoved(CacheGroupEvent event) {  
  107.     }  
  108.   
  109.     public void cacheGroupRemoved(CacheGroupEvent event) {  
  110.     }  
  111.   
  112.     public void cacheGroupUpdated(CacheGroupEvent event) {  
  113.     }  
  114.   
  115.     /** 
  116.      * Called by the cache administrator class when a cache is instantiated. 
  117.      * 
  118.      * @param cache the cache instance that this listener is attached to. 
  119.      * @param config The cache's configuration details. This allows the event handler 
  120.      * to initialize itself based on the cache settings, and also to receive <em>additional</em> 
  121.      * settings that were part of the cache configuration but that the cache 
  122.      * itself does not care about. If you are using <code>cache.properties</code> 
  123.      * for your configuration, simply add any additional properties that your event 
  124.      * handler requires and they will be passed through in this parameter. 
  125.      * 
  126.      * @throws InitializationException thrown when there was a problem initializing the 
  127.      * listener. The cache administrator will log this error and disable the listener. 
  128.      */  
  129.     public void initialize(Cache cache, Config config) throws InitializationException {  
  130.         this.cache = cache;  
  131.     }  
  132.   
  133.     /** 
  134.      * Handles incoming notification messages. This method should be called by the 
  135.      * underlying broadcasting implementation when a message is received from another 
  136.      * node in the cluster. 
  137.      * 
  138.      * @param message The incoming cluster notification message object. 
  139.      */  
  140.     public void handleClusterNotification(ClusterNotification message) {  
  141.         if (cache == null) {  
  142.             log.warn("A cluster notification (" + message + ") was received, but no cache is registered on this machine. Notification ignored.");  
  143.   
  144.             return;  
  145.         }  
  146.   
  147.         if (log.isInfoEnabled()) {  
  148.             log.info("Cluster notification (" + message + ") was received.");  
  149.         }  
  150.   
  151.         switch (message.getType()) {  
  152.             case ClusterNotification.FLUSH_KEY:  
  153.                 cache.flushEntry((String) message.getData(), CLUSTER_ORIGIN);  
  154.                 break;  
  155.             case ClusterNotification.FLUSH_GROUP:  
  156.                 cache.flushGroup((String) message.getData(), CLUSTER_ORIGIN);  
  157.                 break;  
  158.             case ClusterNotification.FLUSH_PATTERN:  
  159.                 cache.flushPattern((String) message.getData(), CLUSTER_ORIGIN);  
  160.                 break;  
  161.             case ClusterNotification.FLUSH_CACHE:  
  162.                 cache.flushAll((Date) message.getData(), CLUSTER_ORIGIN);  
  163.                 break;  
  164.             default:  
  165.                 log.error("The cluster notification (" + message + ") is of an unknown type. Notification ignored.");  
  166.         }  
  167.     }  
  168.   
  169.     /** 
  170.      * Called when a cluster notification message is to be broadcast. Implementing 
  171.      * classes should use their underlying transport to broadcast the message across 
  172.      * the cluster. 
  173.      * 
  174.      * @param message The notification message to broadcast. 
  175.      */  
  176.     abstract protected void sendNotification(ClusterNotification message);  
  177. }  

 
所以我们要集群式同步数据,必须实现这三个方法:

Java代码   收藏代码
  1. public void cacheEntryAdded(CacheEntryEvent event) {  
  2.     }  
  3.   
  4.     public void cacheEntryRemoved(CacheEntryEvent event) {  
  5.     }  
  6.   
  7.     public void cacheEntryUpdated(CacheEntryEvent event) {  
  8.     }  

 这个实现类实现了以上的三个方法,就可以同步数据了:

Java代码   收藏代码
  1. package com.test;  
  2. import com.opensymphony.oscache.base.events.CacheEntryEvent;  
  3. import com.opensymphony.oscache.plugins.clustersupport.ClusterNotification;  
  4. import com.opensymphony.oscache.plugins.clustersupport.JavaGroupsBroadcastingListener;  
  5.   
  6. public class JavaGroupsBroadcastingListenerImpl extends  
  7.         JavaGroupsBroadcastingListener {  
  8.     public void handleClusterNotification(ClusterNotification message) {  
  9.           
  10.         switch (message.getType()) {  
  11.         case CacheConstants.CLUSTER_ENTRY_ADD:  
  12.             System.out.println("集群新增:" + message.getData());  
  13.             if(message.getData() instanceof QflagCacheEvent) {  
  14.                 QflagCacheEvent event = (QflagCacheEvent)message.getData();  
  15.                 cache.putInCache(event.getKey(), event.getEntry().getContent(),null,null,CLUSTER_ORIGIN);  
  16.             }  
  17.             break;  
  18.         case CacheConstants.CLUSTER_ENTRY_UPDATE:  
  19.             System.out.println("集群更新:" + message.getData());  
  20.             if(message.getData() instanceof QflagCacheEvent) {  
  21.                 QflagCacheEvent event = (QflagCacheEvent)message.getData();  
  22. //              cache.flushEntry(event.getKey());  
  23.                 cache.putInCache(event.getKey(), event.getEntry().getContent(),null,null,CLUSTER_ORIGIN);  
  24.             }  
  25.             break;  
  26.         case CacheConstants.CLUSTER_ENTRY_DELETE:  
  27.             System.out.println("集群删除:" + message.getData());  
  28.             if(message.getData() instanceof QflagCacheEvent) {  
  29.                 QflagCacheEvent event = (QflagCacheEvent)message.getData();  
  30. //              cache.removeEntry(event.getKey(),event.getOrigin());  
  31.                 cache.removeEntry(event.getKey());  
  32.             }  
  33.             break;  
  34.         }  
  35.   
  36.     }  
  37.       
  38.     public void cacheEntryAdded(CacheEntryEvent event) {  
  39.         super.cacheEntryAdded(event);  
  40.         System.out.println("属性添加");  
  41.         if(!CLUSTER_ORIGIN.equals(event.getOrigin())) {  
  42.             sendNotification(new ClusterNotification(CacheConstants.CLUSTER_ENTRY_ADD, new QflagCacheEvent(event.getMap(),event.getEntry(),CLUSTER_ORIGIN)));  
  43.         }  
  44.     }  
  45.   
  46. //  @Override  
  47. //  public void cacheEntryFlushed(CacheEntryEvent event) {  
  48. //        
  49. //      super.cacheEntryFlushed(event);  
  50. //      if(!CLUSTER_ORIGIN.equals(event.getOrigin())) {  
  51. //          sendNotification(new ClusterNotification(CacheConstants.CLUSTER_ENTRY_ADD, new UcallCacheEvent(event.getMap(),event.getEntry(),CLUSTER_ORIGIN)));  
  52. //      }  
  53. //  }  
  54.   
  55.     @Override  
  56.     public void cacheEntryRemoved(CacheEntryEvent event) {  
  57.         System.out.println("属性移除");  
  58.         super.cacheEntryRemoved(event);  
  59.         if(!CLUSTER_ORIGIN.equals(event.getOrigin())) {  
  60.             sendNotification(new ClusterNotification(CacheConstants.CLUSTER_ENTRY_DELETE, new QflagCacheEvent(event.getMap(),event.getEntry(),CLUSTER_ORIGIN)));  
  61.         }  
  62.     }  
  63.   
  64.     @Override  
  65.     public void cacheEntryUpdated(CacheEntryEvent event) {  
  66.         System.out.println("属性更新");  
  67.         super.cacheEntryUpdated(event);  
  68.         if(!CLUSTER_ORIGIN.equals(event.getOrigin())) {  
  69.             sendNotification(new ClusterNotification(CacheConstants.CLUSTER_ENTRY_UPDATE, new QflagCacheEvent(event.getMap(),event.getEntry(),CLUSTER_ORIGIN)));  
  70.         }  
  71.     }  
  72.       
  73. }  

 

然后修改配置文件,映射cache.event.listeners类的路径:

Java代码   收藏代码
  1. cache.event.listeners=com.test.JavaGroupsBroadcastingListenerImpl  
  2. cache.cluster.properties=UDP(mcast_addr=231.12.21.132;mcast_port=45566;ip_ttl=32;\  
  3. mcast_send_buf_size=150000;mcast_recv_buf_size=80000):\  
  4. PING(timeout=2000;num_initial_members=3):\  
  5. MERGE2(min_interval=5000;max_interval=10000):\  
  6. FD_SOCK:VERIFY_SUSPECT(timeout=1500):\  
  7. pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800;max_xmit_size=8192):\  
  8. UNICAST(timeout=300,600,1200,2400):\  
  9. pbcast.STABLE(desired_avg_gossip=20000):\  
  10. FRAG(frag_size=8096;down_thread=false;up_thread=false):\  
  11. pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_local_addr=true)  
  12. cache.cluster.multicast.ip=231.12.21.132  

 具体源码可以参考 oscache集群功能  http://rwl6813021.iteye.com/blog/246473,我已经实现了整合。

测试使用两个tomcat6.0,无问题,但是一个tomca6.0,一个tomcat7.0时发现缓存没有同步。。。

猜你喜欢

转载自lishuaishuai.iteye.com/blog/2370055