论坛首页 Java企业应用论坛

扩展Tomcat 6.x,使用memcached存放session信息

浏览 102931 次
该帖已经被评为精华帖
作者 正文
   发表时间:2007-05-22  
看到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.iteye.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">
</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





  • tomcatmemsession.rar (6.1 KB)
  • 描述: tomcatmemsession.jar 内包含源代码 MemcachedManager.java 和MemcachedSession.java
  • 下载次数: 3493
   发表时间:2007-05-22  

使用servlet过滤器方式至少需要写:HttpSessionWrapper.java,MemcachedSnaHttpSessionWrapper.java
MemcachedSnaHttpServletRequestWrapper.java,MemcachedSnaFilter.java
等四个文件,并且依赖cookie来传递snaid,无法做到公用jsessionid,但是好处是可以在不同的servlet容器使用。

直接扩展tomcat的方式比较简便,不过只能在tomcat上用。



3 请登录后投票
   发表时间:2007-05-22  
你的工作很有价值!使得普通Java Web应用在tomcat上面一下具备了SNA架构的能力,有空的时候我会测试一下你的方案,review一下代码。
0 请登录后投票
   发表时间:2007-05-22  
codeutil 写道

使用servlet过滤器方式至少需要写:HttpSessionWrapper.java,MemcachedSnaHttpSessionWrapper.java
MemcachedSnaHttpServletRequestWrapper.java,MemcachedSnaFilter.java
等四个文件,并且依赖cookie来传递snaid,无法做到公用jsessionid,但是好处是可以在不同的servlet容器使用。

直接扩展tomcat的方式比较简便,不过只能在tomcat上用。

Tangosol Coherence的做法就是通过HttpSessionWrapper的方式来把http session存储到tangosol的cache server。
1 请登录后投票
   发表时间:2007-05-22  
很好的思路,这几天正在想一个小方案,用的就是低效的方法-将session持久化到数据库..
0 请登录后投票
   发表时间:2007-05-22  
粗略的看了下楼主的代码,好像没有处理存储在memcached中的session的失效。因为每当有请求到达tomcat时,容器会调用session的access()方法设置session的最后访问时间,同时StandardManager有个后台线程定期调用processExpires()方法删除所有的失效session。
我在代码里没找到对这两个方法的覆写,所以推断memcached端的session失效并没有正确处理。由于memcached本身支持设置失效时间(可以设置全局的,也可以每个cache单独通过api设置),因此只要改写session的access方法,在每次请求时,设置cache最后的访问时间,让memcached自动管理session的失效。
1 请登录后投票
   发表时间:2007-05-22  

代码是前天临时调了一下,很多地方都考虑的不完善,有兴趣的朋友请一起来完善。 比如加入oscache等。
1 请登录后投票
   发表时间:2007-05-22  
codeutil 写道

代码是前天临时调了一下,很多地方都考虑的不完善,有兴趣的朋友请一起来完善。 比如加入oscache等。

加入oscache是出于什么考虑呢,我认为使用memcached作为中心session服务器之后,就没必要再用oscache来存储session了。
1 请登录后投票
   发表时间:2007-05-22  

加入oscache的目的减少对memcached的访问次数。
假设启动了20个tomcat,
假如某个attribute,序列化之后的内容长度为10k,

在30分钟内被读取了100次,修改了两次,
如果只使用memcached的话,需要向memcached读取100次,
产生100*10=1M的网络流量,
而使用了oscache的话,
只需要向memcached读取三次,在属性值发生变化的时候,其它tomcat将会收到2*20次缓存失效的jgroups消息。

这样的开销是远远低于对memcached的不停访问的,也减少了序列化和反序列化的开销。
2 请登录后投票
   发表时间:2007-05-22  
我倾向于不在session存放业务数据,在session一般只存放userId信息,所以session中存储的数据是不会变的,而与session相关的数据,不如购物车之类的,由相应的业务逻辑来处理(要不要cache和如何cache是业务逻辑层的事情),毕竟在业务逻辑层cache数据比在tomcat这个层面简单多了。
既然session存储的数据不会变,自然也就不需要oscache之类支持cluster的cache了,只要一个简单map的可以,map找不到再到memcached server找(基本上可以重用tomcat原先的session实现),当然如果你的设计会把一些可能变化的数据放到session中,确实需要使用oscache。

PS:oscache应该是一级cache,memcached才是二级cache吧
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics