http://www.javaeye.com/topic/81641
在开发大规模网站程序时,一般会让开发人员尽量采用Cookie而非Session来存 储一些状态相关的数据,例如用户登录信息等等。原因是不推荐做Session复制,而多个应用服务器之间为了共享Session所采取的做法无非就是采用 多播技术的Session复制,另外一种则是将Session持久化到数据库。
第二种做法性能很差,第一种做法在应用服务器节点非常多的时候复制的代价很高。
为此这段时间我考虑能不能将缓存系统引入来作为应用服务器的Session存储呢?
由于涉及的应用服务器核心系统,我这个思路主要是针对Tomcat的。我想通过引入memcached来做为Tomcat存放Session的系统,这样 任意多个Tomcat节点都可以直接存取memcached上存放的Session,可以达到共享Session数据的目的,同时因为是基于内存的缓存系 统,因此性能上也有了保障。
接下来就是研究Tomcat的源码,找出Tomcat在处理Session这块功能对应的代码,到目前已经发现该如何来实现这个设想了,只需要扩展 Tomcat的 org.apache.catalina.session.ManagerBase 即可。
看到javayou的刘东关于扩展Tomcat的Session存取机制的思考:
http://www.javayou.com/html/diary/showlog.vm?sid=2&log_id=8534
结合自己曾经写好的在过servlet滤器实现session存放到memcached的代码,
采取扩展 org.apache.catalina.session包下 一共新增MemcachedManager 和 MemcachedSession即可。
实现MemcachedManager继承 org.apache.catalina.session.StandardManager,
MemcachedSession继承 org.apache.catalina.session.StandardSession。
动手试了一下,搞定getAttribute和setAttribute和expire,removeAttribute。
测试步骤如下:
1.首先从http://www.javaeye.com/topic/24505
下载memcached的windows版本。
2.下载相关的jar,需要log4j.jar,commons-logging.jar,commons-logging-adapters.jar,commons-logging-api.jar,java_memcached-release_1.5.1.jar
复制到x:/apache-tomcat-6.0.13/lib下面。
3。然后下载本文附件tomcatmemsession.rar,然后改名为tomcatmemsession.jar,也复制到x:/apache-tomcat-6.0.13/lib下面。
4.将tomcatmemsession.jar里的context.xml替换x:/apache-tomcat-6.0.13/conf下同名文件。
(主要是context.xml里增加了
- <Manager className="org.apache.catalina.session.MemcachedManager" serverlist="127.0.0.1:11212" snaidPerfix="snaid" snaidFlag="true">
- lt;/Manager>
)
5.运行memcached.exe。
(可以运行memcached.exe -vv , -vv可以在控制台显示日志信息 )
6。启动tomcat,在web应用中setAttribute设置支持序列化的属性值。
7. 然后重起tomcat,在再浏览器里访问,jsp读取相关属性的值(使用getAttribute方法),将 发现相应属性值都可以正常读取。
(getAttributeNames没有重写,因此无法遍历方式读取属性,只能通过getAttribute读取)
在自己通过servlet过滤器方式实现的时候,使用了oscache分布式cache,这样可以减少对memcached的访问次数。
但是在MemcachedSession里使用oscache的时候,出现点小问题,没时间仔细检查,于是把oscache去掉了。
有空再加上oscache作为二级缓存。
tomcatmemsession.jar 内包含源代码 MemcachedManager.java 和MemcachedSession.java
TOMCAT6.0.18 SESSION持久化办法
Tomcat里,系统提供Session的持久化策略。
Session的存储提供两种办法:
一、本地文件存储
二、数据库存储
1、进入tomcat的配置文档目录/conf,可以看到context.xml文件,我们将在这里配置Session持久化,配置后将对所有的站点生效。
2、打开context.xml,在<Context>节点下添加如下<Manager>节点:
<Manager className="org.apache.catalina.session.PersistentManager" >
debug="0"
saveOnRestart="false"
maxActiveSession="-1"
minIdleSwap="-1"
maxIdleSwap="-1"
maxIdleBackup="-1"
<Store className="org.apache.catalina.session.FileStore"
directory="../session" />
//这里代表的是文件持久化,也可以自己实现Store。
</Manager>
参数:
className:Session持久化的管理类,tomcat将会通过定义的接口来应用该类生成的对象。
debug:Session管理器的跟踪级别。
saveOnRestart:(true/false)配置服务重启工程中对session的处理,若为true,则关闭前把有效的session保存,启动后重新载入。
maxActiveSession:存放在内存中可处于活动状态的Session的最大数量,为-1时则不限制,否则Session Manager将会把超出该数量的Session对象转移到Session Store中。
minIdleSwap:Session不活动的最短时间,超过该时间,Session Manager 可能会把该Session对象转移到Session Store中,单位为秒。
maxidleSwap:Session不活动的最长时间,超过该时间,Session Manager 将会把该Session对象转移到Session Store中,该Session将不在内存中。
maxidleBackup: Session不活动的最长时间,超过该时间,Session Manager 将会把该Session对象备份到Session Store中,但该Session对象依然存在内存中。
<Store>指定实现持久化的类和Session存放的文件位置,如该例子中指定的类是:
org.apache.catalina.session.FileStore,而Session对象存放的目录则是tomcat根目录下(apache-tomcat-6.0.18/work/Catalina/localhost/)的session文件夹(当然自己创建)
JDBCStore配置:
<Store calssName="org.apache.catalina.session.JDBCStore"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:@localhost:1521:Ora817"
connectionName="b2b"
connectionPassword="b2b"
sessionTable="tomcat_session"
sessionIdCol="session_id"
sessionDataCol="session_data"
sessionValidCol="session_valid"
sessionMaxInactiveCol="max_inactive"
sessionLastAccessedCol="last_access"
sessionAppCol="app_name"
checkInterval="60" debug="99" />
--Session表
create table TOMCAT_SESSION
(
SESSION_ID VARCHAR2(200),
SESSION_DATA CLOB,
SESSION_VALID VARCHAR2(1),
MAX_INACTIVE NUMBER,
LAST_ACCESS NUMBER,
APP_NAME VARCHAR2(200)
);
配置完后可以写一个简单的jsp页面,在页面上显示本次用户访问的Session ID,然后重起tomcat,再刷新该页面,可以看到该Session Id不变,而在/session目录下自动生成一个以session id为名,以“session”为扩展名的文件。该Session的持久化配置成功。
参考配置:Seesion两分钟不活动转移,活动的Session超过500个转移。
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="120" saveOnRestart="false" maxActiveSession="500">
<Store className="org.apache.catalina.session.FileStore"/>
</Manager>