最近项目设计集群,实现了一下session的共享功能,其原理是将session保存到分布式缓存数据库中如:redis, memcache等,然后多个服务器tomcat
每次请求都通过NoSql数据库查询,如果存在,则获取值;反之存放值。
我是通过redis来实现session的共享,其主要有一下两种方法:
1、通过tomcat服务器的拓展功能实现
这种方式比较简单,主要是通过继承session的ManagerBase类,实现重写session相关的方法,这种比较简单,
参考源码链接(http://download.youkuaiyun.com/detail/fengshizty/9417242)。
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
/**
* 创建时间:2016年1月21日 下午7:55:41
*
* @author andy
* @version 2.2
*/
public class HttpSessionWrapper implements HttpSession {
private String sid = "";
private HttpSession session;
private HttpServletRequest request;
private HttpServletResponse response;
private Map<String, Object> map = null;
private SessionService sessionService = (SessionService) SpringContextHolder.getBean("sessionService");
public HttpSessionWrapper() {
}
public HttpSessionWrapper(HttpSession session) {
this.session = session;
}
public HttpSessionWrapper(String sid, HttpSession session) {
this(session);
this.sid = sid;
}
public HttpSessionWrapper(String sid, HttpSession session,
HttpServletRequest request, HttpServletResponse response) {
this(sid, session);
this.request = request;
this.response = response;
}
private Map<String, Object> getSessionMap() {
if (this.map == null) {
this.map = sessionService.getSession(this.sid);
}
return this.map;
}
@Override
public Object getAttribute(String name) {
if (this.getSessionMap() != null) {
Object value = this.getSessionMap().get(name);
return value;
}
return null;
}
@Override
public void setAttribute(String name, Object value) {
this.getSessionMap().put(name, value);
sessionService.saveSession(this.sid, this.getSessionMap());
}
@Override
public void invalidate() {
this.getSessionMap().clear();
sessionService.removeSession(this.sid);
CookieUtil.removeCookieValue(this.request,this.response, GlobalConstant.JSESSIONID);
}
@Override
public void removeAttribute(String name) {
this.getSessionMap().remove(name);
sessionService.saveSession(this.sid, this.getSessionMap());
}
@Override
public Object getValue(String name) {
return this.session.getValue(name);
}
@SuppressWarnings("unchecked")
@Override
public Enumeration getAttributeNames() {
return (new Enumerator(this.getSessionMap().keySet(), true));
}
@Override
public String[] getValueNames() {
return this.session.getValueNames();
}