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

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

参考BLOG

tomcatStandardManagerAPI文档

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

tomcatStandardSessionAPI文档

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:

packagecom.sillycat.easytomcatplugin.sna;

importjava.io.IOException;

importorg.apache.catalina.LifecycleException;

importorg.apache.catalina.Session;

importorg.apache.catalina.session.StandardManager;

importorg.apache.catalina.session.StandardSession;

importcom.danga.MemCached.MemCachedClient;

importcom.danga.MemCached.SockIOPool;

publicclassMemcachedManagerextendsStandardManager{

//memcached客户端

protectedMemCachedClientmc=null;

//Sock池

protectedSockIOPoolpool=null;

protectedStringsockPoolname="snasessionsock";

//服务器队列

protectedStringserverlist="127.0.0.1:11211";

protectedStringsnaidPrefix="snaid";

protectedStringsnaidFlag="true";

publicMemcachedManager(){

super();

}

//重写父类findSession方法,将snaidPrefix加入到SESSIONID中当前缀,先试图从memcached中取出session

publicSessionfindSession(Stringid)throwsIOException{

Sessionsession=super.findSession(id);

if(session==null&&id!=null){

try{

Objectsid=mc.get(this.getSnaidPrefix()+id);

if(sid!=null){

session=createSession(id);

}

}catch(Exceptionex){

ex.printStackTrace();

}

}

returnsession;

}

//创建session,并初始化进memcached

publicSessioncreateSession(StringsessionId){

Sessionsession=super.createSession(sessionId);

mc.set(this.getSnaidPrefix()+session.getId(),session);

returnsession;

}

//创建session

protectedStandardSessiongetNewSession(){

returnnewMemcachedSession(this,mc);

}

protectedvoidinitPool(){

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(Exceptionex){

log.error("error:",ex);

}

}

}catch(Exceptionex){

log.error("error:",ex);

}

if(mc==null){

mc=newMemCachedClient();

//mc.setPoolName(sockPoolName);

mc.setCompressEnable(false);

mc.setCompressThreshold(0);

}

}

protectedvoidclosePool(){

if(mc!=null){

try{

}catch(Exceptionex){

log.error("error:",ex);

}

mc=null;

}

if(pool!=null){

try{

pool.shutDown();

}catch(Exceptionex){

log.error("error:",ex);

}

}

}

publicStringgetSockPoolName(){

returnsockPoolName;

}

publicStringgetServerlist(){

returnserverlist;

}

publicStringgetSnaidPrefix(){

returnsnaidPrefix;

}

publicStringgetSnaidFlag(){

returnsnaidFlag;

}

publicvoidsetSockPoolName(StringsockPoolName){

this.sockPoolName=sockPoolName;

}

publicvoidsetServerlist(Stringserverlist){

this.serverlist=serverlist;

}

publicvoidsetSnaidPrefix(StringsnaidPrefix){

this.snaidPrefix=snaidPrefix;

}

publicvoidsetSnaidFlag(StringsnaidFlag){

this.snaidFlag=snaidFlag;

}

protectedStringgenerateSessionId(){

if(this.getJvmRoute()!=null){

returnjava.util.UUID.randomUUID().toString()+'.'

+this.getJvmRoute();

}

returnjava.util.UUID.randomUUID().toString();

}

//启动

publicvoidstart()throwsLifecycleException{

this.setPathname("");//mustdisablesessionpersistenceacrossTomcat

//restarts

super.start();

this.initPool();

}

//停止

publicvoidstop()throwsLifecycleException{

super.stop();

this.closePool();

}

}

类MemcachedSession.java如下:

packagecom.sillycat.easytomcatplugin.sna;

importorg.apache.catalina.Manager;

importorg.apache.catalina.session.StandardSession;

importcom.danga.MemCached.MemCachedClient;

publicclassMemcachedSessionextendsStandardSession{

privatestaticfinallongserialVersionUID=-3520419866432555766L;

protectedtransientMemCachedClientmc=null;

//构造器

publicMemcachedSession(Managermanager,MemCachedClientmc){

super(manager);

this.mc=mc;

}

//得到属性

publicObjectgetAttribute(Stringname){

Objectobj=super.getAttribute(name);

if(obj!=null&&!(objinstanceofjava.io.Serializable)){

returnobj;

}

Stringkey=name+this.getId();

obj=mc.get(key);

returnobj;

}

//设置属性

publicvoidsetAttribute(Stringname,Objectvalue){

removeAttribute(name);

super.setAttribute(name,value);

if(value!=null&&valueinstanceofjava.io.Serializable){

Stringkey=name+this.getId();

mc.set(key,value);

}

}

//删除属性

protectedvoidremoveAttributeInternal(Stringname,booleannotify){

super.removeAttributeInternal(name,notify);

Stringkey=name+this.getId();

mc.delete(key);

}

//超时过期

publicvoidexpire(booleannotify){

mc.delete(((MemcachedManager)manager).getSnaidPrefix()+this.getId());

super.expire(notify);

}

}

我是部署在两个tomcat上的,分别是tomcat1和tomcat2,修改conf下面的context.xml配置文件如下:

<Managerclassname="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来做代理,配置的是循环访问模式:

backendlogon_server

modehttp

optionhttpchkGET/easylogon/ping.jsp

serverapp1127.0.0.1:8080weight3check

serverapp2127.0.0.1:8081weight3check

backendstatic_server

modehttp

optionhttpchkGET/easystatic/ping.jsp

serverapp3127.0.0.1:8080weight3check

serverapp4127.0.0.1:8081weight3check

经过测试,虽然登陆访问后,server在tomcat1和tomcat2上不断切换,但是session中的数据可以很好的SNA。

相关推荐