最近一直在看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();
}
}
}
}
分享到:
相关推荐
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、...
本文将详细介绍MSM(Memcached_Session_Manager)的使用,包括所需的jar包和在Tomcat中的配置。 MSM(Memcached_Session_Manager)是一个基于Java的Memcached会话管理器,它允许我们将Web应用的session数据存储在...
为了优化这个问题,我们可以使用`memcached-session-manager`,它是一个专门为Tomcat设计的插件,使得Tomcat能够将用户的session数据存储在Memcached服务器上,实现session的分布式管理。 本文将详细介绍如何在...
通过这样的配置,当用户的session在任一Tomcat实例上创建后,会自动同步到Memcached中。其他实例在接收到同一用户的请求时,可以从Memcached中获取session数据,从而实现session的跨服务器共享。这种解决方案可以...
3. **memcached-session-manager-1.5.1.jar**:这个jar是Memcached Session Manager的核心组件,负责管理Tomcat的session并将其与Memcached服务器同步。它支持多种序列化策略,并提供了session失效、备份和恢复等...
【标题】:在Tomcat 7.52中使用memcached进行Session同步 【内容】: 在现代Web应用中,Session同步是确保用户状态在集群环境中一致性的关键。当一个应用部署在多台服务器上时,传统的session管理方式可能会导致...
本文记录了我在生产环境下使用memcached实现tomcat session会话共享解决方案的实施完整过程,验证可用!有需要的请拿走.
3. **Session复制与同步**:当用户在集群中的任意一台服务器上创建或更新Session时,`MemcachedSessionManager`会自动将Session数据序列化并发送到`Memcached`集群,其他服务器在需要时可以从`Memcached`中获取。...
Memcached-Session-Manager的基本配置涉及在每个Tomcat实例的`context.xml`或`server.xml`中添加一个`Manager`元素,指定使用`MemcachedBackupSessionManager`。配置包括Memcached服务器的地址、端口、超时时间等...
这样做是因为这些库提供了Servlet监听器,可以在每次会话开始时注册,将新的会话保存到memcached,并在会话结束时清除。 4. **配置Servlet容器**:在Tomcat的`context.xml`或`web.xml`配置文件中,我们需要添加相应...
最后,"memcached-session-manager-tc8-1.9.6.jar"是针对Tomcat8特定的适配器,确保了这个session管理器能够与Tomcat8的生命周期和API无缝集成。这个适配器处理了Tomcat8特有的配置和交互细节,让开发者无需深入了解...
标题 "memcached-session-manager 实现 tomcat session共享" 指的是在分布式环境中,通过 memcached-session-manager 这个工具来实现 Tomcat 应用服务器之间的 Session 共享。Session 是 Web 应用中用于存储用户状态...
2. **配置Tomcat**: 在Tomcat的`conf/server.xml`文件中,找到或添加`Manager`元素,指定使用`memcached-session-manager`。例如: ```xml memcachedNodes="n1:192.168.1.1:11211 n2:192.168.1.2:11211" ...
当用户在任一Tomcat实例上登录或创建session后,这个session数据会被同步到Memcached。之后,无论用户请求哪个Tomcat实例,Nginx都会根据session ID查找对应的session数据,从而保持用户状态的一致性。 5. **配置...
session+memcached Memcached配置需要下载以下jar包并放在tomcat...如果tomcat过多不建议session同步,server间相互同步session很耗资源,高并发环境容易引起Session风暴。请根据自己应用情况合理采纳session解决方案。
4. **处理Session复制**:在Java应用中,每当Session有变化(如添加、修改或删除属性),都会通过配置的Session管理器同步到memcached。同样,当应用启动时,会从memcached加载已有的Session。 5. **处理Session...
【标题】"tomcat6+session+memcached" 涉及的知识点主要集中在Web服务器Tomcat6的配置与使用,以及如何通过Memcached实现Session的共享存储。 【描述】"jdk7+tomcat6+memcached。依赖包" 提示了这个环境是基于Java ...
本文将深入探讨如何在Tomcat7中使用`memcached-session-manager`进行会话同步。 `memcached-session-manager`是一个开源项目,它允许Tomcat容器将用户的会话数据存储在Memcached缓存服务器上,从而实现跨服务器的...
然后,Tomcat会在每次session创建、更新或删除时,通过memcached客户端与memcached服务器通信,同步session数据。这样,即使用户在集群中的不同Tomcat实例之间切换,session信息也能保持一致。 此外,使用memcached...
本篇将深入探讨如何使用Memcached实现Tomcat的Session共享,并基于提供的jar文件和Tomcat的XML配置进行详细讲解。 首先,我们需要理解Memcached的工作原理。Memcached是一个基于内存的键值对存储系统,用于临时存储...