该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2007-05-22
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 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-05-22
使用servlet过滤器方式至少需要写:HttpSessionWrapper.java,MemcachedSnaHttpSessionWrapper.java MemcachedSnaHttpServletRequestWrapper.java,MemcachedSnaFilter.java 等四个文件,并且依赖cookie来传递snaid,无法做到公用jsessionid,但是好处是可以在不同的servlet容器使用。 直接扩展tomcat的方式比较简便,不过只能在tomcat上用。 |
|
返回顶楼 | |
发表时间:2007-05-22
你的工作很有价值!使得普通Java Web应用在tomcat上面一下具备了SNA架构的能力,有空的时候我会测试一下你的方案,review一下代码。
|
|
返回顶楼 | |
发表时间: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。 |
|
返回顶楼 | |
发表时间:2007-05-22
很好的思路,这几天正在想一个小方案,用的就是低效的方法-将session持久化到数据库..
|
|
返回顶楼 | |
发表时间:2007-05-22
粗略的看了下楼主的代码,好像没有处理存储在memcached中的session的失效。因为每当有请求到达tomcat时,容器会调用session的access()方法设置session的最后访问时间,同时StandardManager有个后台线程定期调用processExpires()方法删除所有的失效session。
我在代码里没找到对这两个方法的覆写,所以推断memcached端的session失效并没有正确处理。由于memcached本身支持设置失效时间(可以设置全局的,也可以每个cache单独通过api设置),因此只要改写session的access方法,在每次请求时,设置cache最后的访问时间,让memcached自动管理session的失效。 |
|
返回顶楼 | |
发表时间:2007-05-22
代码是前天临时调了一下,很多地方都考虑的不完善,有兴趣的朋友请一起来完善。 比如加入oscache等。 |
|
返回顶楼 | |
发表时间:2007-05-22
codeutil 写道 代码是前天临时调了一下,很多地方都考虑的不完善,有兴趣的朋友请一起来完善。 比如加入oscache等。 加入oscache是出于什么考虑呢,我认为使用memcached作为中心session服务器之后,就没必要再用oscache来存储session了。 |
|
返回顶楼 | |
发表时间:2007-05-22
加入oscache的目的减少对memcached的访问次数。 假设启动了20个tomcat, 假如某个attribute,序列化之后的内容长度为10k, 在30分钟内被读取了100次,修改了两次, 如果只使用memcached的话,需要向memcached读取100次, 产生100*10=1M的网络流量, 而使用了oscache的话, 只需要向memcached读取三次,在属性值发生变化的时候,其它tomcat将会收到2*20次缓存失效的jgroups消息。 这样的开销是远远低于对memcached的不停访问的,也减少了序列化和反序列化的开销。 |
|
返回顶楼 | |
发表时间: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吧 |
|
返回顶楼 | |