改进基于filter的远程分布式session存储
<!--StartFragment-->
参考了网上一些资料,实现了session通过filter存储到memcached服务器上.
(参见: http://ooft.javaeye.com/blog/537841 )
实现方式:
a) 通过MemcachedSessionFilter过滤器拦截cookie,取得的sessionId,通过sessionId构造新的HttpServletRequestWrapper对象,传给后面的应用.
b) 继承重构HttpServletRequestWrapper,HttpSessionWrapper类,覆盖原来和session存取相关的方法呢,都通过SessionService类来实现.
c) SessionService连接memcached服务,以sessionId作为key,存取的对象是一个map.map的内容即为session的内容.
d) 读取数据时,先通过sessionId从memcached服务器上获取整个map对象,再以session的attributeName作为key从map中获取数据对象.写数据的方式与读数据类似,先获取map,然后修改map中的值,然后将整个map保存到memcached服务器上.
改进内容:
(1) 使用xmemcached客户端代替java memcached client.
XMemcached同样是基于java nio的客户端,java nio相比于传统阻塞io模型来说,有效率高(特别在高并发下)和资源耗费相对较少的优点。
(2) 对修改和删除session属性时,使用cas方法实现,防止在并发时出现数据覆盖的问题.
原来的代码:
public void saveSession(String id, Map session) { long s1= System.currentTimeMillis(); MemCachedClient mc = this.getMemCachedClient(); mc.replace(id, session); System.out.print("saveSession"); System.out.println(System.currentTimeMillis() -s1); }
其中保存进去的session是一个通过get方法从memcached上获取的map对象,将map中的值修改以后,将map对象替换服务器上的对象.如果在多台机器并发的情况下,很可能出现一个线程写进去的数据被其它的覆盖.
改进后的代码:
Memcached是通过cas协议实现原子更新,所谓原子更新就是compare and set,原理类似乐观锁,每次请求存储某个数据同时要附带一个cas值,memcached比对这个cas值与当前存储数据的cas值是否相等,如果相等就让新的数据覆盖老的数据,如果不相等就认为更新失败,这在并发环境下特别有用。
public void saveSession(String id,String key, Object arg1) { long s1= System.currentTimeMillis(); final String k=key; final Object o=arg1; try { mc.cas(id,0,new CASOperation<Map>(){ //尝试更新5次 public int getMaxTries() { return 5; } public Map getNewValue(long currentCAS, Map map) { map.put(k, o); return map; }}); System.out.print("saveSession"); } finally{ System.out.println(System.currentTimeMillis() -s1); } }
-
本文附件下载:
- xmemsession.rar (719.5 KB)
作者: ooft
声明: 本文系JavaEye网站发布的原创文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
已有 0 人发表回复,猛击->>这里<<-参与讨论
JavaEye推荐
- 上海:天会皓闻诚聘CTO技术总监
- 北京:手机之家网站诚聘PHP程序员
- 成都:月薪5千到1万招聘Java开发工程师
- 上海:月薪1-2万诚聘资深PHP开发人员
- 上海:高薪诚聘Python开发人员
- 北京:高薪招聘Java搜索开发工程师
- 上海:天会皓闻诚聘资深Java架构师
出处:http://fervour.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。