利用JGroups同步两台server之间的cache。

一、需求
前段时间做了一个项目,在后台有很多的数据都放入到了cache中了,而且还会对cache中的数据进行更新。如果只有一台server没有任何问题,但是如果考虑到集群负载平衡,连接多个server的时候,就有问题出现了,怎么样才能保证多个server之间cache的同步呢?请看下面的部署图。

二、引入JGroups
JGroups是一个可靠的组间通讯工具,进程可以加入一个通讯组,给组内所有的成员或单独的成员发送消息,同样,也可以从组中的成员处接收消息。
系统会记录组的每一个成员,在新成员加入或是现有的成员离开或是崩溃时,会通知组内的其他成员。

当我们更新一台server上的cache的时候,利用JGroups进行广播,其他的server接收到广播,根据接收到的信息来更新自己的cache,这样达到了
每个server的cache同步。

三、实现
1、定义一个接口BaseCache规定出对cache类操作的方法

 1ExpandedBlockStart.gifContractedBlock.gifpublic interface BaseCache dot.gif{
 2InBlock.gif    
 3InBlock.gif    public void put(String key, Object ob);
 4InBlock.gif    public Object get(String key);
 5InBlock.gif    
 6InBlock.gif    public void delete(String key);
 7InBlock.gif    public void batchDelete(String[] list);
 8InBlock.gif    public void batchDelete(List list);
 9InBlock.gif    public void deleteAll();
10InBlock.gif    
11ExpandedBlockEnd.gif}


2、定义一个同步器(CacheSynchronizer),这个类利用JGroups进行发送广播和接收广播

 1ExpandedBlockStart.gifContractedBlock.gifpublic class CacheSynchronizer dot.gif{
 2InBlock.gif    private static String protocolStackString=
 3InBlock.gif        "UDP(mcast_addr=235.11.17.19;mcast_port=32767;ip_ttl=3;"+
 4InBlock.gif        "mcast_send_buf_size=150000;mcast_recv_buf_size=80000):"+
 5InBlock.gif        "PING(timeout=2000;num_initial_members=3):"+
 6InBlock.gif        "MERGE2(min_interval=5000;max_interval=10000):"+
 7InBlock.gif        "FD_SOCK:"+
 8InBlock.gif        "VERIFY_SUSPECT(timeout=1500):"+
 9InBlock.gif        "pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800):"+
10InBlock.gif        "pbcast.STABLE(desired_avg_gossip=20000):"+
11InBlock.gif        "UNICAST(timeout=2500,5000):"+
12InBlock.gif        "FRAG:"+
13InBlock.gif        "pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_local_addr=false)";
14InBlock.gif    private static String groupName="YHPTEST";
15InBlock.gif    
16InBlock.gif    private Channel jgroupsChannel=null;
17InBlock.gif    
18InBlock.gif    //inner class ,定义接收广播,已经对接收到的广播进行处理
19ExpandedSubBlockStart.gifContractedSubBlock.gif    private class ReceiveCallback extends ExtendedReceiverAdapterdot.gif{
20InBlock.gif        private BaseCache cache=null;
21ExpandedSubBlockStart.gifContractedSubBlock.gif        public void setCache(BaseCache baseCache)dot.gif{//设置cache类
22InBlock.gif            cache=baseCache;
23ExpandedSubBlockEnd.gif        }

24ExpandedSubBlockStart.gifContractedSubBlock.gif        public void receive(Message msg) dot.gif{
25InBlock.gif            if(cache==nullreturn ;
26InBlock.gif            String strMsg = (String) msg.getObject();
27ExpandedSubBlockStart.gifContractedSubBlock.gif            if(strMsg!=null&&(!"".equals(strMsg)))dot.gif{
28InBlock.gif                cache.put(strMsg, strMsg);    //根据接收到的广播,同步cache
29ExpandedSubBlockEnd.gif            }

30ExpandedSubBlockEnd.gif        }

31ExpandedSubBlockEnd.gif    }

32InBlock.gif    
33InBlock.gif    private ReceiveCallback recvCallback = null;
34InBlock.gif    
35ExpandedSubBlockStart.gifContractedSubBlock.gif    public CacheSynchronizer(BaseCache cache) throws Exceptiondot.gif{
36InBlock.gif        jgroupsChannel = new JChannel(protocolStackString);
37InBlock.gif        recvCallback = new ReceiveCallback();
38InBlock.gif        recvCallback.setCache(cache);
39InBlock.gif        jgroupsChannel.setReceiver(recvCallback);
40InBlock.gif        jgroupsChannel.connect(groupName);
41ExpandedSubBlockEnd.gif    }

42InBlock.gif    
43ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//**
44InBlock.gif     * 发送广播信息,我们可以自定义广播的格式。
45InBlock.gif     * 这里简单起见,仅仅发送一个字符串
46InBlock.gif     * @param sendMsg
47InBlock.gif     * @throws Exception
48ExpandedSubBlockEnd.gif     */

49ExpandedSubBlockStart.gifContractedSubBlock.gif    public void sendCacheFlushMessage(String sendMsg)throws Exception dot.gif{
50InBlock.gif        jgroupsChannel.send(nullnull, sendMsg); //发送广播
51InBlock.gif        
52ExpandedSubBlockEnd.gif    }

53ExpandedBlockEnd.gif}


3、定义cache类,调用同步器同步cache

 1ExpandedBlockStart.gifContractedBlock.gifpublic class TestDataCache implements BaseCache dot.gif{
 2InBlock.gif    private Map dataCache=null;//保持cache数据
 3InBlock.gif    private CacheSynchronizer cacheSyncer = null//同步器
 4InBlock.gif    
 5InBlock.gif    //inner class for thread safe.
 6ExpandedSubBlockStart.gifContractedSubBlock.gif    private static final class TestDataCacheHolddot.gif{
 7InBlock.gif        private static TestDataCache  theSingleton=new TestDataCache();        
 8ExpandedSubBlockStart.gifContractedSubBlock.gif        public static TestDataCache getSingleton()dot.gif{
 9InBlock.gif            return theSingleton;
10ExpandedSubBlockEnd.gif        }

11ExpandedSubBlockStart.gifContractedSubBlock.gif        private TestDataCacheHold()dot.gif{}
12ExpandedSubBlockEnd.gif    }

13InBlock.gif    
14InBlock.gif    //Prevents to inherit
15ExpandedSubBlockStart.gifContractedSubBlock.gif    private TestDataCache()dot.gif{
16InBlock.gif        dataCache=new HashMap();
17InBlock.gif        createSynchronizer();
18ExpandedSubBlockEnd.gif    }

19InBlock.gif    
20ExpandedSubBlockStart.gifContractedSubBlock.gif    public static TestDataCache getInstance()dot.gif{
21InBlock.gif        return TestDataCacheHold.getSingleton();
22ExpandedSubBlockEnd.gif    }

23InBlock.gif    
24ExpandedSubBlockStart.gifContractedSubBlock.gif    public CacheSynchronizer getSynchronizer()dot.gif{
25InBlock.gif        return cacheSyncer;
26ExpandedSubBlockEnd.gif    }

27InBlock.gif    
28ExpandedSubBlockStart.gifContractedSubBlock.gif    public int getCacheLength()dot.gif{
29InBlock.gif        return dataCache.size();
30ExpandedSubBlockEnd.gif    }

31InBlock.gif    
32ExpandedSubBlockStart.gifContractedSubBlock.gif    public void createSynchronizer()dot.gif{
33ExpandedSubBlockStart.gifContractedSubBlock.gif        trydot.gif{
34InBlock.gif            cacheSyncer=new CacheSynchronizer(this);
35ExpandedSubBlockStart.gifContractedSubBlock.gif        }
catch(Exception e)dot.gif{
36InBlock.gif            e.printStackTrace();
37ExpandedSubBlockEnd.gif        }

38ExpandedSubBlockEnd.gif    }

39InBlock.gif    
40ExpandedSubBlockStart.gifContractedSubBlock.gif    public void batchDelete(String[] list) dot.gif{
41InBlock.gif        if(list!=nullreturn ;
42ExpandedSubBlockStart.gifContractedSubBlock.gif        synchronized (dataCache)dot.gif{
43ExpandedSubBlockStart.gifContractedSubBlock.gif            for(int i=0;i<list.length;i++)dot.gif{
44ExpandedSubBlockStart.gifContractedSubBlock.gif                if(list[i].length()>0)dot.gif{
45InBlock.gif                    dataCache.remove(list[i]);
46ExpandedSubBlockEnd.gif                }

47ExpandedSubBlockEnd.gif            }

48ExpandedSubBlockEnd.gif        }

49InBlock.gif
50ExpandedSubBlockEnd.gif    }

51InBlock.gif
52ExpandedSubBlockStart.gifContractedSubBlock.gif    public void batchDelete(List list) dot.gif{
53ExpandedSubBlockStart.gifContractedSubBlock.gif        synchronized (dataCache)dot.gif{
54InBlock.gif            Iterator itor=list.iterator();
55ExpandedSubBlockStart.gifContractedSubBlock.gif            while(itor.hasNext())dot.gif{
56InBlock.gif                String tmpKey=(String)itor.next();
57ExpandedSubBlockStart.gifContractedSubBlock.gif                if(tmpKey.length()>0)dot.gif{
58InBlock.gif                    dataCache.remove(tmpKey);
59ExpandedSubBlockEnd.gif                }

60ExpandedSubBlockEnd.gif            }

61ExpandedSubBlockEnd.gif        }

62ExpandedSubBlockEnd.gif    }

63InBlock.gif
64ExpandedSubBlockStart.gifContractedSubBlock.gif    public void delete(String key) dot.gif{
65ExpandedSubBlockStart.gifContractedSubBlock.gif        synchronized (dataCache) dot.gif{
66InBlock.gif            dataCache.remove(key);
67ExpandedSubBlockEnd.gif        }

68ExpandedSubBlockEnd.gif    }

69InBlock.gif
70ExpandedSubBlockStart.gifContractedSubBlock.gif    public void deleteAll() dot.gif{
71ExpandedSubBlockStart.gifContractedSubBlock.gif        synchronized (dataCache)dot.gif{
72InBlock.gif            dataCache.clear();
73ExpandedSubBlockEnd.gif        }

74InBlock.gif
75ExpandedSubBlockEnd.gif    }

76InBlock.gif
77ExpandedSubBlockStart.gifContractedSubBlock.gif    public Object get(String key) dot.gif{
78InBlock.gif        Object theObj=null;
79ExpandedSubBlockStart.gifContractedSubBlock.gif        synchronized (dataCache) dot.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值