分布式Session的一个实现.
本来一个Tomcat集群4台服务器工作的很好,随着访问量的增加本来的粘性Session方式的配置没办法很好的一碗水端平了.Session复制的话对于网络又是一个负担,所以才自己实现了一套利用Memcache的Session实现.
网上已经有很多这样的实现了,比如修改Tomcat的Manager的http://code.google.com/p/memcached-session-manager/.
但由于我这里还有其他的Servlet容器,所以也就没有使用完全自己实现了一套,现在运行在www.etnet.com.cn网站上.
从那开始呢....其他的Servlet容器我总不能再一一去实现吧。。。。最后还是决定使用过滤器来偷梁换柱了.
先是 CacheSessionFilter ,这个过滤器负责将普通的HttpServletRequest替换成我们自己的实现.
public class CacheSessionFilter extends BaseFilter { ** * 替换原始的Request,修改为 * com.etnetchina.servlet.wrapper.CacheSessionHttpServletReqeust。 * 并根据是否新生成了Session来更新客户端的cookie. * * @param request 请求。 * @param response 响应。 * @param chain 下一个过滤器。 * @throws java.io.IOException * @throws javax.servlet.ServletException */ public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { logger.debugLog("CacheSessionFilter to work."); HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; CacheSessionHttpServletReqeust cacheRequest = new CacheSessionHttpServletReqeust( httpRequest, httpResponse, filterConfig.getServletContext()); cacheRequest.setSessionCookieName(sessionCookieName); cacheRequest.setMaxInactiveInterval(maxInactiveInterval); cacheRequest.setCookieDomain(cookieDomain); cacheRequest.setCookieContextPath(cookieContextPath); cacheRequest.setSessionAttributeListeners(sessionAttributeListeners); cacheRequest.setSessionListeners(sessionListeners); chain.doFilter(cacheRequest, httpResponse); CacheHttpSession cacheSession = cacheRequest.currentSession(); if (cacheSession != null) { if (!cacheSession.synchronizationCache()) { WebUtil.failureCookie( httpRequest, httpResponse, sessionCookieName, cookieDomain, cookieContextPath); } } }}
private HttpSession doGetSession(boolean create) { if (cacheSession != null) { //local,return. logger.debugLog("Session[{0}] was existed.", cacheSession.getId()); } else { Cookie cookie = WebUtil.findCookie(this, getSessionCookieName()); if (cookie != null) { logger.debugLog("Find session`s id from cookie.[{0}]", cookie.getValue()); cacheSession = buildCacheHttpSession(cookie.getValue(), false); } else { cacheSession = buildCacheHttpSession(create); } } if (cacheSession != null) { //dead? if (cacheSession.isInvalid()) { cacheSession.invalidate(); cacheSession.synchronizationCache(); cacheSession = buildCacheHttpSession(create); } if (cacheSession != null) { cacheSession.access(); } } return cacheSession;}
<filter> <description>修改默认的Session储存机制,改为使用某个缓存来储存。</description> <filter-name>CacheSessionFilter</filter-name> <filter-class>com.etnetchina.servlet.filter.session.CacheSessionFilter</filter-class> <init-param> <description>sessionId在Cookie中的名称</description> <param-name>sessionCookieName</param-name> <param-value>etnetsessionid</param-value> </init-param> <init-param> <description>Session的最大不活动时间(秒)</description> <param-name>maxInactiveInterval</param-name> <param-value>60</param-value> </init-param> </filter>
<filter-mapping> <filter-name>CacheSessionFilter</filter-name> <url-pattern>/*</url-pattern></filter-mapping>