您的位置:首页 > 数据库 > Memcache

基于memcached的SNA实现(2)

2008-11-23 17:04 253 查看
二、 Session失效的处理

采用memcached作为httpsession的存储,并不直接保存httpsession对象,自定义SessionMap,SessionMap直接继承HashMap,保存SessionMap。

会话胶粘:未失败转发的情况下没必要在memcached保存的SessionMap和httpsession之间复制来复制去,眉来眼去。

利用memcached计数器保存在线人数。

系统权限采用了acegi,在acegi的拦截器链里配置snaFilter

<bean id="filterChainProxy"

class="org.acegisecurity.util.FilterChainProxy">

<property name="filterInvocationDefinitionSource">

<value>

CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON

PATTERN_TYPE_APACHE_ANT


/**=snaFilter,httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,exceptionTranslationFilter,filterInvocationInterceptor

</value>

</property>

</bean>

注意需要配置在第一个。

snaFilter的职责:

1、 没有HttpSession时,创建HttpSession;

2、 创建Cookie保存HttpSession id;

3、 如果Cookie保存的HttpSession id与当前HttpSession id一致,说明是正常请求;

4、 如果Cookie保存的HttpSession id与当前HttpSession id不一致,说明是失败转发;失败转发的处理:

4.1、根据Cookie保存的HttpSession id从memcached获取SessionMap;

4.2、SessionMap属性复制到当前HttpSession;

4.3、memcached删除SessionMap。

5、 判断当前请求url是否是登出url,是则删除SessionMap,在线人数减1.

代码:

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,

FilterChain filterChain) throws IOException, ServletException {

final HttpServletRequest hrequest = (HttpServletRequest) servletRequest;

final HttpServletResponse hresponse = (HttpServletResponse) servletResponse;

String uri = hrequest.getRequestURI();

logger.debug("开始SNA拦截-----------------" + uri);

HttpSession httpSession = hrequest.getSession();

String sessionId = httpSession.getId();

//如果是登出,则直接干掉sessionMap

if (uri.equals(logoutUrl)) {

logger.debug("remove sessionmap:" + sessionId);

//在线人数减1

getCache().addOrDecr("userCount",1);

getCache().remove(sessionId);

} else {

String cookiesessionid = getSessionIdFromCookie(hrequest, hresponse);

if (!sessionId.equals(cookiesessionid)) {

createCookie(sessionId, hresponse);

SessionMap sessionMap = getSessionMap(cookiesessionid);

if (sessionMap != null) {

logger.debug("fail over--------sessionid:" + sessionId + "cookiesessionid:" + cookiesessionid);

initialHttpSession(sessionMap, httpSession);

cache.remove(cookiesessionid);

}

}

}

filterChain.doFilter(hrequest, hresponse);

}

利用HttpSessionAttributeListener监听httpsession的属性变化,同步到memecached中的sessionmap。
public void attributeAdded(HttpSessionBindingEvent event) {

HttpSession httpSession = event.getSession();

String attrName = event.getName();

Object attrValue = event.getValue();

String sessionId = httpSession.getId();

logger.debug("attributeAdded sessionId:" + sessionId + "name:" + attrName + ",value:" + attrValue);

SessionMap sessionMap = getSessionMap(sessionId);

if (sessionMap == null){

//在线人数加1

getCache().addOrIncr("userCount",1);

sessionMap = new SessionMap();

}

logger.debug("name:" + attrName + ",value:" + attrValue);

sessionMap.put(attrName, attrValue);

getCache().put(sessionId, sessionMap);

}

public void attributeRemoved(HttpSessionBindingEvent event) {

HttpSession httpSession = event.getSession();

String attrName = event.getName();

String sessionId = httpSession.getId();

logger.debug("attributeRemoved sessionId:" + sessionId + "name:" + attrName);

SessionMap sessionMap = getSessionMap(sessionId);

if (sessionMap != null) {

logger.debug("remove:" + attrName);

sessionMap.remove(attrName);

getCache().put(sessionId, sessionMap);

}

}

public void attributeReplaced(HttpSessionBindingEvent event) {

attributeAdded(event);

}
利用HttpSessionListener,sessionDestroyed事件时根据sessionid删除memcached里的sessionMap(如果存在)。不再担心httpsession的过期问题。
public void sessionDestroyed(HttpSessionEvent event) {

HttpSession httpSession = event.getSession();

String sessionId = httpSession.getId();

logger.debug("session Removed sessionId:" + sessionId);

SessionMap sessionMap = getSessionMap(sessionId);

if (sessionMap != null) {

logger.debug("remove sessionmap:" + sessionId);

//在线人数减1

getCache().addOrDecr("userCount",1);

getCache().remove(sessionId);

}

}

三、 文件保存的处理

和缓存类似,采用集中式的文件服务。对于linux,采用nfs。参考文档http://linux.vbird.org/linux_server/0330nfs.php#What_NFS_perm。关键在于对权限的分配。

应用程序本身不用修改。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: