分布式系统开发常见问题 1. session的复制与共享
1.session的复制与共享
在web应用中,为了应对大规模访问,必须实现应用的集群部署.要实现集群部署主要需要实现session共享机制,使得多台应用服务器之间会话统一, tomcat等多数主流web服务器都采用了session复制以及实现session的共享. 但问题还是很明显的

在节点持续增多的情况下,session复制带来的性能损失会快速增加.特别是当session中保存了较大的对象,而且对象变化较快时,性能下降更加显著.这种特性使得web应用的水平扩展受到了限制.
session共享的另一种思路就是把session集中起来管理,首先想到的是采用数据库来集中存储session,但数据库是文件存储相对内存慢了一个数量级,同时这势必加大数据库系统的负担.所以需要一种既速度快又能远程集中存储的服务:memcached或者redis

2.1使用memcached来存储session有三种方案:
(1)直接通过tomcat6的扩展机制实现.
Reference: http://www.javaeye.com/topic/81641
(2)通过自己编写filter实现.
考虑到系统的扩展,我们采用这种方案.这样可以使session共享机制和中间件脱钩.
Reference: http://www.javaeye.com/topic/82565

主要思路:
1)继承重构HttpServletRequestWrapper,HttpSessionWrapper类,覆盖原来和session存取相关的方法呢,都通过SessionService类来实现.
2)使用filter拦截cookie中的sessionId,通过sessionId构造新的HttpServletRequestWrapper对象,传给后面的应用.
3)SessionService连接memcached服务,以sessionId作为key,存取的对象是一个map.    map的内容即为session的内容.

使用过程注意几个问题和改进思路:
1、memcache的内存应该足够大,这样不会出现用户session从Cache中被清除的问题(可以关闭memcached的对象退出机制)。
2、如果session的读取比写入要多很多,可以在memcache前再加一个Oscache等本地缓存,减少对memcache的读操作,从而减小网络开销,提高性能。
3、如果用户非常多,可以使用memcached组,通过set方法中带hashCode,插入到某个memcached服务器

(3)使用memcached-session-manager管理session
Reference: http://www.iteye.com/topic/1125301

3.1 redis来实现session的共享,其主要有一下两种方法:
1、通过tomcat服务器的拓展功能实现
这种方式比较简单,主要是通过继承session的ManagerBase类,实现重写session相关的方法,这种比较简单,
参考源码链接()。
2、通过filter拦截request请求实现
下面主要介绍这样实现方式:
(1)写HttpSessionWrapper实现HttpSession接口,实现里面session相关的方法。
(2)写HttpServletRequestWrapper继承javax.servlet.http.HttpServletRequestWrapper类,重写对于session 相关的方法
(3)写SessionFilter拦截配置的请求url,过去cookie中
的sessionId,如果为空,对此次请求重写生成一个新的sessionId,在sessionId构造新的HttpServletRequestWrapper对象
(4)写SessionService实现session到redis的保存和过去,其key为sessionId,value为session对于的Map
3、代码实现
(1)HttpSessionWrapper