改造tomcat6.x支持SNA(一)实践

改造tomcat6.x支持SNA(一)实践

参考BLOG
http://www.iteye.com/topic/81641

tomcat StandardManager API文档
http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/session/StandardManager.html

tomcat StandardSession API文档
http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/session/StandardSession.html

下载老版本的TOMCAT(tomcat3-5)
http://archive.apache.org/dist/jakarta/

tomcat6.x下载
http://tomcat.apache.org/download-60.cgi

先参考网上资料,实现TOMCAT的扩展,其中比较核心的两个类StandardManager和StandardSession,代码清单如下:
MemcachedManager.java:
package com.sillycat.easytomcatplugin.sna;
import java.io.IOException;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Session;
import org.apache.catalina.session.StandardManager;
import org.apache.catalina.session.StandardSession;
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
public class MemcachedManager extends StandardManager {
// memcached客户端
protected MemCachedClient mc = null;
// Sock池
protected SockIOPool pool = null;
protected String sockPoolName = "snasessionsock";
// 服务器队列
protected String serverlist = "127.0.0.1:11211";
protected String snaidPrefix = "snaid";
protected String snaidFlag = "true";
public MemcachedManager() {
   super();
}
// 重写父类findSession方法,将snaidPrefix加入到SESSIONID中当前缀,先试图从memcached中取出session
public Session findSession(String id) throws IOException {
   Session session = super.findSession(id);
   if (session == null && id != null) {
    try {
     Object sid = mc.get(this.getSnaidPrefix() + id);
     if (sid != null) {
      session = createSession(id);
     }
    } catch (Exception ex) {
     ex.printStackTrace();
    }
   }
   return session;
}
// 创建session,并初始化进memcached
public Session createSession(String sessionId) {
   Session session = super.createSession(sessionId);
   mc.set(this.getSnaidPrefix() + session.getId(), session);
   return session;
}
// 创建session
protected StandardSession getNewSession() {
   return new MemcachedSession(this, mc);
}
protected void initPool() {
   try {
    if (pool == null) {
     try {
      pool = SockIOPool.getInstance(sockPoolName);
      pool.setServers(serverlist.split(","));
      pool.setInitConn(5);
      pool.setMinConn(5);
      pool.setMaxConn(50);
      pool.setMaintSleep(30);
      pool.setNagle(false);
      pool.initialize();
     } catch (Exception ex) {
      log.error("error:", ex);
     }
    }
   } catch (Exception ex) {
    log.error("error:", ex);
   }
   if (mc == null) {
    mc = new MemCachedClient();
    // mc.setPoolName(sockPoolName);
    mc.setCompressEnable(false);
    mc.setCompressThreshold(0);
   }
}
protected void closePool() {
   if (mc != null) {
    try {
    } catch (Exception ex) {
     log.error("error:", ex);
    }
    mc = null;
   }
   if (pool != null) {
    try {
     pool.shutDown();
    } catch (Exception ex) {
     log.error("error:", ex);
    }
   }
}
public String getSockPoolName() {
   return sockPoolName;
}
public String getServerlist() {
   return serverlist;
}
public String getSnaidPrefix() {
   return snaidPrefix;
}
public String getSnaidFlag() {
   return snaidFlag;
}
public void setSockPoolName(String sockPoolName) {
   this.sockPoolName = sockPoolName;
}
public void setServerlist(String serverlist) {
   this.serverlist = serverlist;
}
public void setSnaidPrefix(String snaidPrefix) {
   this.snaidPrefix = snaidPrefix;
}
public void setSnaidFlag(String snaidFlag) {
   this.snaidFlag = snaidFlag;
}
protected String generateSessionId() {
   if (this.getJvmRoute() != null) {
    return java.util.UUID.randomUUID().toString() + '.'
      + this.getJvmRoute();
   }
   return java.util.UUID.randomUUID().toString();
}
// 启动
public void start() throws LifecycleException {
   this.setPathname(""); // must disable session persistence across Tomcat
   // restarts
   super.start();
   this.initPool();
}
// 停止
public void stop() throws LifecycleException {
   super.stop();
   this.closePool();
}
}

类MemcachedSession.java如下:
package com.sillycat.easytomcatplugin.sna;
import org.apache.catalina.Manager;
import org.apache.catalina.session.StandardSession;
import com.danga.MemCached.MemCachedClient;
public class MemcachedSession extends StandardSession {
private static final long serialVersionUID = -3520419866432555766L;
protected transient MemCachedClient mc = null;
//构造器
public MemcachedSession(Manager manager, MemCachedClient mc) {
   super(manager);
   this.mc = mc;
}
//得到属性
public Object getAttribute(String name) {
   Object obj = super.getAttribute(name);
   if (obj != null && !(obj instanceof java.io.Serializable)) {
    return obj;
   }
   String key = name + this.getId();
   obj = mc.get(key);
   return obj;
}
//设置属性
public void setAttribute(String name, Object value) {
   removeAttribute(name);
   super.setAttribute(name, value);
   if (value != null && value instanceof java.io.Serializable) {
    String key = name + this.getId();
    mc.set(key, value);
   }
}
//删除属性
protected void removeAttributeInternal(String name, boolean notify) {
   super.removeAttributeInternal(name, notify);
   String key = name + this.getId();
   mc.delete(key);
}
//超时过期
public void expire(boolean notify) {
   mc.delete(((MemcachedManager) manager).getSnaidPrefix() + this.getId());
   super.expire(notify);
}
}
我是部署在两个tomcat上的,分别是tomcat1和tomcat2,修改conf下面的context.xml配置文件如下:
<Manager className="com.sillycat.easytomcatplugin.sna.MemcachedManager"
       serverlist="127.0.0.1:11211" snaidPrefix="snaid" snaidFlag="true">
</Manager>
其中的serverlist以,号分隔不同的server,另外这个snaidPrefix在不同的tomcat上要写成snaid1,snaid2;最后这个snaidFlag虽然有标示,应该是一个使能,但是程序明显没有使用。

另外要将两个memcached用到的jar包拷贝到tomcat/lib中,分别是:
log4j-1.2.15.jar
memcached-2.0.1.jar
另外就是我们写的这两个类:
easytomcatplugin-1.0.jar


在redhat上,我是使用的haproxy来做代理,配置的是循环访问模式:
backend logon_server
        mode http
        option httpchk GET /easylogon/ping.jsp
        server app1 127.0.0.1:8080 weight 3 check
        server app2 127.0.0.1:8081 weight 3 check
backend static_server
        mode http
        option httpchk GET /easystatic/ping.jsp
        server app3 127.0.0.1:8080 weight 3 check
        server app4 127.0.0.1:8081 weight 3 check
经过测试,虽然登陆访问后,server在tomcat1和tomcat2上不断切换,但是session中的数据可以很好的SNA。

你可能感兴趣的:(apache,tomcat,jsp,redhat,memcached)