`
wqy_blue3316
  • 浏览: 9341 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

怎样使用Memcached做Session同步

阅读更多
最近一直在看Xmemcached,希望能够通过它实现TOMCAT集群的Session复制,因为TOMCAT自己带的那个SESSION复制功能,当节点多了之后容易出错,且不稳定,还有就是不能同步Application里的东西,这几天捣鼓了很久,倒是把Application里的东西整合好了,但是让我头痛的是Session同步,不知道 这里有没有大侠做过类似的研究开发,希望能一起讨论下。
关于Application同步的代码我贴下:求指教
public class ClusterHelper {
	 
	private static final Logger logger = Logger.getLogger(ClusterHelper.class);
	private static String APPKEY = ApplicationHelper.APPKEY;
	private static boolean SysMemCached = ApplicationHelper.SysMemCached.equals("1")?true:false;
	
	public static void initMemcached(){  //系统首次启动的时候,初始化Memcached链接
		MemcachedClient memcachedClient = null;
		try{
			if(SysMemCached && ApplicationHelper.XMEMCACHEDCLIENT == null){
		         XMemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses("192.168.0.153:11211"));
		         builder.setConnectionPoolSize(50);
		         builder.addStateListener(new MemcachedListener());
		         builder.setCommandFactory(new BinaryCommandFactory());            
		         memcachedClient = builder.build();
		         memcachedClient.setConnectTimeout(20000);
		         memcachedClient.setMergeFactor(100);   //默认是150,缩小到50
		         memcachedClient.setOptimizeMergeBuffer(true);  //开启合并buffer的优化
		         memcachedClient.setEnableHeartBeat(false); //关闭心跳检测 暂时关闭  以后要开启
		         logger.debug("Create XMemcached Client successfully PoolSize:50 ConnectTimeout:20000ms !");
		         ApplicationHelper.XMEMCACHEDCLIENT = memcachedClient;
		         if(memcachedClient.get("CasHash")==null){
		        	 memcachedClient.add("CasHash", 0, new Hashtable());
		         }
		         if(ApplicationHelper.SysMenCasHash==null){
		        	 ApplicationHelper.SysMenCasHash = new Hashtable();
		         }
			}else{
				 //memcachedClient = ApplicationHelper.XMEMCACHEDCLIENT;
				 logger.debug("XMemcached Client Is Already In Application PoolSize:50 ConnectTimeout:20000ms !");
			}
	    }catch(Exception e){
	       e.printStackTrace();
	       ApplicationHelper.SysMemCached = "0";
	       logger.debug("Create XMemcached Client throws a Exception!");
	    }
	}
	
	
	/**
	 * 根据KEY检查对象在本地是否为最新(Application)
	 * @param mc
	 * @param key
	 * @return
	 */
	public static boolean isNewObj(MemcachedClient mc,String key){
		boolean flag = false;		
		try {
			String MApplicatonKey = APPKEY+key;
			Hashtable table = (Hashtable)mc.get("CasHash");  //记录在Memcached中存储的Application对象的版本号
			Hashtable Apptable = ApplicationHelper.SysMenCasHash;  //记录本节点上所有Application对象的版本号
			if(table==null || Apptable==null){
				return false;
			}			
			Long MemCas = (Long)table.get(MApplicatonKey);
			Long AppCas = (Long)Apptable.get(MApplicatonKey);
			if(MemCas==null || AppCas==null){
				return false;
			}
			
			logger.debug(((Long)table.get(MApplicatonKey)).longValue()==((Long)Apptable.get(MApplicatonKey)).longValue());
			
			if(((Long)table.get(MApplicatonKey)).longValue()==((Long)Apptable.get(MApplicatonKey)).longValue()){ //根据KEY比较本地与Memcached中的版本是否一致
				flag = true;
			}			
		} catch (TimeoutException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (MemcachedException e) {
			e.printStackTrace();
		}		
		return flag;
	}
	
	
	/**
	 * 更新本地及MEM上关于Application的CASHASH
	 * @param mc
	 * @param key
	 * @param value
	 */
	public static void setCasToHash(MemcachedClient mc,String key,long value){
		try {
			String MApplicatonKey = APPKEY+key;
			Hashtable table = (Hashtable)mc.get("CasHash");
			if(table.containsKey(MApplicatonKey)){
				table.remove(MApplicatonKey);				
			}
			table.put(MApplicatonKey, value);
			mc.replaceWithNoReply("CasHash", 0, table);
			
			Hashtable Apptable = ApplicationHelper.SysMenCasHash;
			if(Apptable.containsKey(MApplicatonKey)){
				Apptable.remove(MApplicatonKey);
			}
			Apptable.put(MApplicatonKey, value);
			ApplicationHelper.SysMenCasHash = Apptable;
			
		} catch (TimeoutException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (MemcachedException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 根据key查看对象是否存在(Application)
	 * @param mc
	 * @param key
	 * @return
	 */
	public static boolean isExist(MemcachedClient mc,String key){
		boolean flag = false;
		try {
			if(((Hashtable)mc.get("CasHash")).containsKey(APPKEY+key)){
				flag = true;
			}
		} catch (TimeoutException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (MemcachedException e) {
			e.printStackTrace();
		}
		return flag;
	}
	
	/**
	 * 根据key删除对象(Application)
	 * @param mc
	 * @param key
	 */
	public static void ReMoveObj(MemcachedClient mc,String key){
		try {
			String MApplicatonKey = APPKEY+key; 
			Hashtable table = (Hashtable)mc.get("CasHash");
			if(table.containsKey(MApplicatonKey)){
				table.remove(MApplicatonKey);				
			}	
			mc.replaceWithNoReply("CasHash", 0, table);
			
			Hashtable Apptable = ApplicationHelper.SysMenCasHash;
			if(Apptable.containsKey(MApplicatonKey)){
				Apptable.remove(MApplicatonKey);
			}
			ApplicationHelper.SysMenCasHash = Apptable;
			
		} catch (TimeoutException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (MemcachedException e) {
			e.printStackTrace();
		}		
	}	
}

public class MemcachedServletContext{
	
	private static final Logger logger = Logger.getLogger(MemcachedServletContext.class);
    private MemcachedClient xmc = ApplicationHelper.XMEMCACHEDCLIENT;//全局XMC链接
    private boolean SysMemCached = ApplicationHelper.SysMemCached.equals("1")?true:false; //系统是否启用Memcached功能
    private String APPKEY = ApplicationHelper.APPKEY; 
	private ServletContext application;
	
	public MemcachedServletContext(ServletContext application){
		this.application = application;
	}
	
	public Object getAttribute(String arg0) {
		Object obj = null;
		if(SysMemCached && !ClusterHelper.isNewObj(xmc, arg0)){	
	        try {
	        	GetsResponse GRObj = xmc.gets(APPKEY+arg0);
	        	
	        	if(GRObj == null) return null;
	        	
	        	obj = GRObj.getValue();
	        	
	        	application.setAttribute(arg0,obj);
	        	
				Hashtable Apptable = ApplicationHelper.SysMenCasHash;
				if(Apptable.containsKey(APPKEY+arg0)){
					Apptable.remove(APPKEY+arg0);
				}
				
				Apptable.put(APPKEY+arg0,GRObj.getCas());
			} catch (TimeoutException e) {
				e.printStackTrace();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (MemcachedException e) {
				e.printStackTrace();
			}			
		}else{
			logger.debug("++++++++++++++++++++++++++");
			return application.getAttribute(arg0);			
		}
        return obj;
	}
	
	public void removeAttribute(String arg0) {
		if(SysMemCached){		
	        try {
				xmc.deleteWithNoReply(APPKEY+arg0);
				ClusterHelper.ReMoveObj(xmc,arg0);
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (MemcachedException e) {
				e.printStackTrace();
			}			
		}		
		application.removeAttribute(arg0);			
	}

	
	public void setAttribute(String arg0, Object arg1) {
		removeAttribute(arg0);
		application.setAttribute(arg0, arg1);
		if(SysMemCached && arg1 instanceof java.io.Serializable){
			try {
				if(ClusterHelper.isExist(xmc, arg0)){
				    //xmc.replaceWithNoReply(APPKEY+arg0, 0, arg1);
					new CASThread(xmc,0,APPKEY+arg0,arg1,new CountDownLatch(1)).start();
				    logger.debug("replace::"+APPKEY+arg0);
				}else{
				    xmc.addWithNoReply(APPKEY+arg0, 0, arg1);
				    logger.debug("add::"+APPKEY+arg0);
				}			
				ClusterHelper.setCasToHash(xmc,arg0,(xmc.gets(APPKEY+arg0)).getCas());
			} catch (TimeoutException e) {
				e.printStackTrace();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (MemcachedException e) {
				e.printStackTrace();
			}
		}
	}

}
分享到:
评论
1 楼 wqy_blue3316 2011-07-08  
自己顶下,难道没有人会么~

相关推荐

    tomcat使用memcached配置session同步的所有jar包

    tomcat使用memcached配置session同步的所有jar包,里面有asm-5.2.jar、kryo-4.0.0.jar、kryo-serializers-0.38.jar、memcached-session-manager-1.9.7.jar、minlog-1.3.0.jar、msm-kryo-serializer-1.9.7.jar、...

    Tomcat通过Memcached实现session共享的完整部署记录

    本文记录了我在生产环境下使用memcached实现tomcat session会话共享解决方案的实施完整过程,验证可用!有需要的请拿走.

    tomcat+memcached 管理session

    memcached 实现session复制与同步需要的一整套jar

    memcached +tomcat7.52 session同步

    memcached tomcat7.52 的session同步 注意tomcat 版本

    session+memcached所需jar

    session+memcached Memcached配置需要下载以下jar包并放在tomcat...如果tomcat过多不建议session同步,server间相互同步session很耗资源,高并发环境容易引起Session风暴。请根据自己应用情况合理采纳session解决方案。

    memcached-session-manager tomcat7

    memcached-session-manager Tomcat7下需要的包。其他版本tomcat没有测试过。

    tomcat6/7/8 集群部署解决Session同步问题的完美解决方案

    网上很多说是支持的,其实都不行,基本上是各个依赖包之间的版本不兼容或者依赖包不全,我这个包是一个一个依赖下载的,完美同步Seesion,解决老架构下的单Web应用,利用集群支持大并发,补救方案。

    Linux下Nginx搭建

    1.Ngnix 下载 ...黄海下载的是: ... 2.Tomcat 下载 ...本例使用的是6.0.35版本的tomcat ... 3.Memcached 下载 ...本例中使用memcached-session-manager 的插件进行session 的同步管理。 http://code.google.com/p/m

    nginx+tomcat7+session共享 kryo序列化所需要包

    Request请求到来时,从memcached 2加载备 session 到 tomcat,(当 容器 中还是没有session 则从memcached1加载主 session 到 tomcat, 这种情况是只有一个memcached节点,或者有memcached1 出错时),Request请求...

    memcached部署

    memcached 缓 存 服 务 器 架 构,高可用部署,session同步

    采用memcache在web集群中实现session的同步会话

    使用memcache来同步session是还是不错的,当然也可以通过redis来保存session,可以php开启并将Session存储到Redis缓存,下面是设置利用memcache在web集群中同步会话session的实现过程: 1、模拟web集群 我启动了二个...

    PHP中使用memcache存储session的三种配置方法

    下面简单说下PHP项目分布式部署中,SESSION的同步方案中的一种,使用Memcache来存储SESSION。并总结了三种配置方式,需要的朋友可以参考下

    nginx1.8+tomcat6+memcatched实现负载均衡以及session共享(含有demo跟相关文件)

    做Tomcat集群的目的是为了提供...当有访问请求时nignx会随机将访问请求分发到tomcat1,tomcat2,为了保持session同步,使用memcached去管理session。 我们配置的环境是:win7,JDK1.7,nginx-1.8,tomcat6 2个,memcached

    第3周 3WEB技术-tomcat 会话同步.html

    (3) session server:redis(store), memcached(cache) 共享存储 分析:新建立一个存放各个tomcat session记录的server,每台tomcat服务器都将自己的session记录在这个服务器中,用户再次访问,每台tomcat 都从这个...

    ASP.NET通过分布式Session提升性能

    如果我们正在使用Session,那么构建高性能可扩展的ASP.NET网站,就必须解决分布式Session的架构,因为单服务器的 SESSION处理能力会很快出现性能瓶颈,这类问题也被称之为Session同步。微软有自己的分布式Session的...

    LVS高级应用详解.txt

    对LVS应用全面讲解,达到高可用,负载均衡双DR做冗余,避免单点故障 使用直接路由调度请求 实现后端节点健康检查 后点节点使用共享存储实现附件目录... 使用memcached存放session和频繁查询但修改比较少的数据的交果

    Nginx+Tomcat+Mencached负载均衡集群部署笔记

    本文档主要讲解,如何在CentOS6.5下搭建Nginx+Tomcat+Memcached负载均衡集群服务器,Nginx负责负载均衡,Tomcat负责实际服务,Memcached负责同步Tomcat的Session,达到Session共享的目的。

    Java数据库持久工具timon.zip

    支持外部数据缓存,支持Ehcache,Memcached和内置同步缓存 提供SQL语句解析、格式化工具 安装方式  <groupId>org.pinae  <artifactId>timon  <version>1.1 实例代码1. XML配置<?xml version="1.0" ...

    网站架构技术

    问题: 负载均衡情况下session状态的保持? 解决方案: 基于DNS的负载均衡 反向代理 ngix JK2 数据库的读写分离 问题: 读库与写库的数据同步 解决方案: 不同的数据库都有自己的数据库...

Global site tag (gtag.js) - Google Analytics