基于memcached的SNA实现
系统要集群,使用SNA方案。
一、缓存的处理
缓存要使用统一的缓存服务器,集中式缓存。
原先的实现采用ehcache。
在spring里的配置,以资源缓存为例:/**
* User: ronghao
* Date: 2008-10-14
* Time: 10:36:30
* 管理Memcached 的CacheManager
*/
public
class
MemcachedCacheManagerFactoryBean
implements
FactoryBean, InitializingBean, DisposableBean {
protected
final
Log logger = LogFactory.getLog(getClass());
private
ICacheManager<IMemcachedCache> cacheManager;
public
Object getObject()
throws
Exception {
return
cacheManager;
}
public
Class getObjectType() {
return
this
.cacheManager.getClass();
}
public
boolean
isSingleton() {
return
true
;
}
public
void
afterPropertiesSet()
throws
Exception {
logger.info("Initializing Memcached CacheManager"
);
cacheManager = CacheUtil.getCacheManager(IMemcachedCache.class
,
MemcachedCacheManager.class
.getName());
cacheManager.start();
}
public
void
destroy()
throws
Exception {
logger.info("Shutting down Memcached CacheManager"
);
cacheManager.stop();
}
} /**
* User: ronghao
* Date: 2008-10-14
* Time: 10:36:30
* 管理Memcached 的CacheManager
*/
public class MemcachedCacheManagerFactoryBean implements FactoryBean, InitializingBean, DisposableBean {
protected final Log logger = LogFactory.getLog(getClass());
private ICacheManager<IMemcachedCache> cacheManager;
public Object getObject() throws Exception {
return cacheManager;
}
public Class getObjectType() {
return this.cacheManager.getClass();
}
public boolean isSingleton() {
return true;
}
public void afterPropertiesSet() throws Exception {
logger.info("Initializing Memcached CacheManager");
cacheManager = CacheUtil.getCacheManager(IMemcachedCache.class,
MemcachedCacheManager.class.getName());
cacheManager.start();
}
public void destroy() throws Exception {
logger.info("Shutting down Memcached CacheManager");
cacheManager.stop();
}
} 配置:
/**
* User: ronghao
* Date: 2008-10-14
* Time: 10:37:16
* 返回 MemcachedCache
*/
public
class
MemcachedCacheFactoryBean
implements
FactoryBean, BeanNameAware, InitializingBean {
protected
final
Log logger = LogFactory.getLog(getClass());
private
ICacheManager<IMemcachedCache> cacheManager;
private
String cacheName;
private
String beanName;
private
IMemcachedCache cache;
public
void
setCacheManager(ICacheManager<IMemcachedCache> cacheManager) {
this
.cacheManager = cacheManager;
}
public
void
setCacheName(String cacheName) {
this
.cacheName = cacheName;
}
public
Object getObject()
throws
Exception {
return
cache;
}
public
Class getObjectType() {
return
this
.cache.getClass();
}
public
boolean
isSingleton() {
return
true
;
}
public
void
setBeanName(String name) {
this
.beanName=name;
}
public
void
afterPropertiesSet()
throws
Exception {
// If no cache name given, use bean name as cache name.
if
(
this
.cacheName ==
null
) {
this
.cacheName =
this
.beanName;
}
cache = cacheManager.getCache(cacheName);
}
} /**
* User: ronghao
* Date: 2008-10-14
* Time: 10:37:16
* 返回 MemcachedCache
*/
public class MemcachedCacheFactoryBean implements FactoryBean, BeanNameAware, InitializingBean {
protected final Log logger = LogFactory.getLog(getClass());
private ICacheManager<IMemcachedCache> cacheManager;
private String cacheName;
private String beanName;
private IMemcachedCache cache;
public void setCacheManager(ICacheManager<IMemcachedCache> cacheManager) {
this.cacheManager = cacheManager;
}
public void setCacheName(String cacheName) {
this.cacheName = cacheName;
}
public Object getObject() throws Exception {
return cache;
}
public Class getObjectType() {
return this.cache.getClass();
}
public boolean isSingleton() {
return true;
}
public void setBeanName(String name) {
this.beanName=name;
}
public void afterPropertiesSet() throws Exception {
// If no cache name given, use bean name as cache name.
if (this.cacheName == null) {
this.cacheName = this.beanName;
}
cache = cacheManager.getCache(cacheName);
}
} 配置:
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);
} 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);
} 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);
}
} 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。关键在于对权限的分配。
应用程序本身不用修改。相关推荐
LinuxJob 2020-06-26
ol0 2020-05-02
carolAnn 2020-03-07
CSDN0BLOG 2020-06-09
郗瑞强 2020-08-16
85590296 2020-07-22
jkzyx 2020-06-29
luotuo 2020-06-26
ol0 2020-06-26
清溪算法君老号 2020-06-25
86251043 2020-06-13
ol0 2020-05-26
andyhuabing 2020-05-22
程序员俱乐部 2020-05-06
83530391 2020-05-05
83530391 2020-04-09
85590296 2020-03-25
大脸猫脸大 2020-03-03
ol0 2020-02-18