oscache分布式缓存

apache + tomcat集群 要考虑session同步 还要考虑缓存同步 在设计的阶段就该考虑到集群的问题,否则真是有解决不完的问题接踵而来,该实现序列化的要实现,单例模式、静态变量、线程同步、定时器什么的,使用的时候就需要慎重考虑,否则到了从单机到集群的时候将会非常痛苦。

 

session同步tomcat可以搞定,缓存同步目前资料较多的是用oscache和ehcache

 

以下记录是搜集整理的一些关于oscache分布式缓存的相关资料:

首先oscache本身是没有实现集群的功能,需要利用第三方支持,此处只记录我实际应用的 oscache + jgroups

 

1、下载oscache所需jar包,官网:http://www.opensymphony.com/oscache/  下载地址:http://java.net/downloads/oscache/ 

      (我用的版本是oscache-2.4.1.jar,是当前最新的。关于oscache的使用就不多写了,这里主要记录集群相关。)

 

2、下载jgroups所需jar包,官网:http://www.jgroups.org/  下载地址:http://sourceforge.net/projects/javagroups/files/JGroups/

      (我用的版本是jgroups-2.11.0.GA.jar,我没有看GA和Final后缀的区别,但是Final的不行,少类,所以就用GA的吧。)

 

3、修改oscache.properties,如果之前没有,创建一个,内容基本不用改动即可。

cache.event.listeners=com.opensymphony.oscache.plugins.clustersupport.JavaGroupsBroadcastingListenerImpl           
cache.memory=true
cache.blocking=true
cache.capacity=100000
cache.algorithm=com.opensymphony.oscache.base.algorithm.UnlimitedCache           
cache.cluster.properties=UDP(mcast_addr=231.12.21.132;mcast_port=45566;ip_ttl=32;mcast_send_buf_size=150000;mcast_recv_buf_size=80000):PING(timeout=2000;num_initial_members=3):MERGE2(min_interval=5000;max_interval=10000):FD_SOCK:VERIFY_SUSPECT(timeout=1500):pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800):pbcast.STABLE(desired_avg_gossip=20000):UNICAST(timeout=5000):FRAG(frag_size=8096;down_thread=false;up_thread=false):pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_local_addr=true)           
cache.cluster.multicast.ip=231.12.21.132


4、oscache并没有实现缓存同步,只提供了相应的通知,所以要创建一个实现类来实现,上面配置的类是创建的实现类,包名.类名是可变更的,对应上配置就行 以下是实现类及相关常量类和序列信息类:

com.opensymphony.oscache.plugins.clustersupport.JavaGroupsBroadcastingListenerImpl 

com.opensymphony.oscache.CacheConstants

com.opensymphony.oscache.event.SerialCacheEvent

package com.opensymphony.oscache.plugins.clustersupport;           
                            
import com.opensymphony.oscache.CacheConstants;           
import com.opensymphony.oscache.base.events.CacheEntryEvent;           
import com.opensymphony.oscache.event.SerialCacheEvent;           
                            
/**           
 * oscache集群监听器,继承自jgroup的监听器,根据需要重写相应的函数来实现通知和同步更新。           
 * @author slzs           
 * Nov 29, 2012 9:14:00 AM           
 * each engineer has a duty to keep the code elegant           
 */
public class JavaGroupsBroadcastingListenerImpl extends JavaGroupsBroadcastingListener {           
    /**           
     * 处理集群通知,接收来自某个节点发来的通知,并进行相应的同步处理           
     * overriding           
     * @see com.opensymphony.oscache.plugins.clustersupport.AbstractBroadcastingListener#handleClusterNotification(com.opensymphony.oscache.plugins.clustersupport.ClusterNotification)           
     * @author: slzs           
     * Nov 29, 2012 9:16:28 AM           
     * @param message            
     * each engineer has a duty to keep the code elegant           
     */
    public void handleClusterNotification(ClusterNotification message) {           
                            
        switch (message.getType()) {           
            case CacheConstants.CLUSTER_ENTRY_ADD:           
                System.out.println("集群新增:" + message.getData());           
                if (message.getData() instanceof SerialCacheEvent) {           
                    SerialCacheEvent event = (SerialCacheEvent) message.getData();           
                    cache.putInCache(event.getKey(), event.getEntry().getContent(), null, null, CLUSTER_ORIGIN);           
                }           
                break;           
            case CacheConstants.CLUSTER_ENTRY_UPDATE:           
                System.out.println("集群更新:" + message.getData());           
                if (message.getData() instanceof SerialCacheEvent) {           
                    SerialCacheEvent event = (SerialCacheEvent) message.getData();           
                    cache.putInCache(event.getKey(), event.getEntry().getContent(), null, null, CLUSTER_ORIGIN);           
                }           
                break;           
            case CacheConstants.CLUSTER_ENTRY_DELETE:           
                System.out.println("集群删除:" + message.getData());           
                if (message.getData() instanceof SerialCacheEvent) {           
                    SerialCacheEvent event = (SerialCacheEvent) message.getData();           
                    cache.removeEntry(event.getKey());           
                }           
                break;           
        }           
                            
    }           
                            
    /**           
     * 新增缓存后通知其它子节点           
     * overriding           
     * @see com.opensymphony.oscache.plugins.clustersupport.AbstractBroadcastingListener#cacheEntryAdded(com.opensymphony.oscache.base.events.CacheEntryEvent)           
     * @author: slzs           
     * Nov 29, 2012 9:17:29 AM           
     * @param event            
     * each engineer has a duty to keep the code elegant           
     */
    @Override   
    public void cacheEntryAdded(CacheEntryEvent event) {           
        super.cacheEntryAdded(event);           
        if (!CLUSTER_ORIGIN.equals(event.getOrigin())) {           
            sendNotification(new ClusterNotification(CacheConstants.CLUSTER_ENTRY_ADD, new SerialCacheEvent(event.getMap(), event.getEntry(), CLUSTER_ORIGIN)));           
        }           
    }           
                            
    /**           
     * 移除缓存后通知其它子节点           
     * overriding           
     * @see com.opensymphony.oscache.plugins.clustersupport.AbstractBroadcastingListener#cacheEntryAdded(com.opensymphony.oscache.base.events.CacheEntryEvent)           
     * @author: slzs           
     * Nov 29, 2012 9:17:29 AM           
     * @param event            
     * each engineer has a duty to keep the code elegant           
     */
    @Override   
    public void cacheEntryRemoved(CacheEntryEvent event) {           
                            
        super.cacheEntryRemoved(event);           
        if (!CLUSTER_ORIGIN.equals(event.getOrigin())) {           
            sendNotification(new ClusterNotification(CacheConstants.CLUSTER_ENTRY_DELETE, new SerialCacheEvent(event.getMap(), event.getEntry(), CLUSTER_ORIGIN)));           
        }           
    }           
                            
    /**           
     * 更新缓存后通知其它子节点           
     * overriding           
     * @see com.opensymphony.oscache.plugins.clustersupport.AbstractBroadcastingListener#cacheEntryAdded(com.opensymphony.oscache.base.events.CacheEntryEvent)           
     * @author: slzs           
     * Nov 29, 2012 9:17:29 AM           
     * @param event            
     * each engineer has a duty to keep the code elegant           
     */
    @Override   
    public void cacheEntryUpdated(CacheEntryEvent event) {           
                            
        super.cacheEntryUpdated(event);           
        if (!CLUSTER_ORIGIN.equals(event.getOrigin())) {           
            sendNotification(new ClusterNotification(CacheConstants.CLUSTER_ENTRY_UPDATE, new SerialCacheEvent(event.getMap(), event.getEntry(), CLUSTER_ORIGIN)));           
        }           
    }           
                            
}


package com.opensymphony.oscache;         
                        
/**         
 * oscache分布式缓存通知所需部分常量         
 * @author slzs         
 * Nov 28, 2012 1:39:20 PM         
 * note each engineer has a duty to keep the code elegant         
 */
public class CacheConstants {         
                        
    /**         
     * 添加缓存对象操作         
     */
    public final static int ACTION_ADD_OBJ = 1;         
    /**         
     * 更新缓存对象操作         
     */
    public final static int ACTION_UPDATE_OBJ = 2;         
    /**         
     * 删除缓存对象操作         
     */
    public final static int ACTION_DELETE_OBJ = 3;         
    /**         
     * 刷新缓存对象         
     */
    public final static int ACTION_FLUSH_OBJ = 4;         
                        
    /**         
     * 集群entry add处理         
     */
    public final static int CLUSTER_ENTRY_ADD = 20;         
                        
    /**         
     * 集群entry update处理         
     */
    public final static int CLUSTER_ENTRY_UPDATE = 21;         
                        
    /**         
     * 集群entry delete处理         
     */
    public final static int CLUSTER_ENTRY_DELETE = 22;         
}


package com.opensymphony.oscache.event;           
                            
import java.io.Serializable;           
                            
import com.opensymphony.oscache.base.Cache;           
import com.opensymphony.oscache.base.CacheEntry;           
import com.opensymphony.oscache.base.events.CacheEvent;           
                            
/**           
 * 序列信息类           
 * @author slzs           
 * Nov 29, 2012 9:37:17 AM           
 * each engineer has a duty to keep the code elegant           
 */
@SuppressWarnings("serial")           
public class SerialCacheEvent extends CacheEvent implements Serializable {           
                            
    private Cache map = null;           
                            
    private CacheEntry entry = null;           
                            
    public SerialCacheEvent(Cache map, CacheEntry entry) {           
        this(map, entry, null);           
    }           
                            
    public SerialCacheEvent(Cache map, CacheEntry entry, String origin) {           
        super(origin);           
        this.map = map;           
        this.entry = entry;           
    }           
                            
    public CacheEntry getEntry() {           
        return entry;           
    }           
                            
    public String getKey() {           
        return entry.getKey();           
    }           
                            
    public Cache getMap() {           
        return map;           
    }           
                            
    public String toString() {           
        return "key=" + entry.getKey();           
    }           
}


5、配上jgroup的日志,log4j.properties 里加入 log4j.logger.org.jgroups.blocks=DEBUG

 

完成了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值