系统要集群,使用SNA方案。
一、 缓存的处理
缓存要使用统一的缓存服务器,集中式缓存。
原先的实现采用ehcache。
在spring里的配置,以资源缓存为例:
-
-
<
bean
id
=
"cacheManager"
class
=
"org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
>
-
<
property
name
=
"configLocation"
>
-
<
value
>
classpath:ehcache.xml
</
value
>
-
</
property
>
-
</
bean
>
-
-
<
bean
id
=
"resourceCacheBackend"
-
class
=
"org.springframework.cache.ehcache.EhCacheFactoryBean"
>
-
<
property
name
=
"cacheManager"
ref
=
"cacheManager"
/>
-
<
property
name
=
"cacheName"
value
=
"resourceCache"
/>
-
</
bean
>
-
-
<
bean
id
=
"resourceCache"
-
class
=
"com.framework.extcomponent.security.authentication.services.acegi.cache.EhCacheBasedResourceCache"
-
autowire
=
"byName"
>
-
<
property
name
=
"cache"
ref
=
"resourceCacheBackend"
/>
-
</
bean
>
cacheManager负责对ehcache进行管理,初始化、启动、停止。
resourceCacheBackend负责实际执行缓存操作,put 、get、remove。
resourceCache实现具有业务语义的业务应用层面的缓存操作,内部调用resourceCacheBackend操作。
现在采用memcached。
关于客户端,采用文初封装的客户端,地址在http://code.google.com/p/memcache-client-forjava/
。
使用spring的FactoryBean进行二次封装。同理:
memcachedManager负责对memcached进行管理,初始化、启动、停止。
代码:
-
-
-
-
-
-
-
public
class
MemcachedCacheManagerFactoryBean
implements
FactoryBean,InitializingBean,DisposableBean{
-
-
protected
final
Loglogger=LogFactory.getLog(getClass());
-
-
private
ICacheManager<IMemcachedCache>cacheManager;
-
-
public
ObjectgetObject()
throws
Exception{
-
return
cacheManager;
-
}
-
-
public
ClassgetObjectType(){
-
return
this
.cacheManager.getClass();
-
}
-
-
public
boolean
isSingleton(){
-
return
true
;
-
}
-
-
public
void
afterPropertiesSet()
throws
Exception{
-
logger.info(
"InitializingMemcachedCacheManager"
);
-
cacheManager=CacheUtil.getCacheManager(IMemcachedCache.
class
,
-
MemcachedCacheManager.
class
.getName());
-
cacheManager.start();
-
}
-
-
public
void
destroy()
throws
Exception{
-
logger.info(
"ShuttingdownMemcachedCacheManager"
);
-
cacheManager.stop();
-
}
-
}
配置:
-
<
bean
id
=
"memcachedManager"
-
class
=
"com.framework.extcomponent.cache.MemcachedCacheManagerFactoryBean"
/>
resourceCacheBackend负责实际执行缓存操作,put 、get、remove。
代码:
-
-
-
-
-
-
-
public
class
MemcachedCacheFactoryBean
implements
FactoryBean,BeanNameAware,InitializingBean{
-
-
protected
final
Loglogger=LogFactory.getLog(getClass());
-
-
private
ICacheManager<IMemcachedCache>cacheManager;
-
private
StringcacheName;
-
private
StringbeanName;
-
private
IMemcachedCachecache;
-
-
public
void
setCacheManager(ICacheManager<IMemcachedCache>cacheManager){
-
this
.cacheManager=cacheManager;
-
}
-
-
public
void
setCacheName(StringcacheName){
-
this
.cacheName=cacheName;
-
}
-
-
public
ObjectgetObject()
throws
Exception{
-
return
cache;
-
}
-
-
public
ClassgetObjectType(){
-
return
this
.cache.getClass();
-
}
-
-
public
boolean
isSingleton(){
-
return
true
;
-
}
-
-
public
void
setBeanName(Stringname){
-
this
.beanName=name;
-
}
-
-
public
void
afterPropertiesSet()
throws
Exception{
-
-
if
(
this
.cacheName==
null
){
-
this
.cacheName=
this
.beanName;
-
}
-
cache=cacheManager.getCache(cacheName);
-
}
-
}
配置:
-
<
bean
id
=
"resourceCacheBackend"
-
class
=
"com.framework.extcomponent.cache.MemcachedCacheFactoryBean"
>
-
<
property
name
=
"cacheManager"
ref
=
"memcachedManager"
/>
-
<
property
name
=
"cacheName"
value
=
"memcache"
/>
-
</
bean
>
resourceCache同上,替换新的实现类MemcachedBasedResourceCache即可。
二、 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(ServletRequestservletRequest,ServletResponseservletResponse,
-
FilterChainfilterChain)
throws
IOException,ServletException{
-
final
HttpServletRequesthrequest=(HttpServletRequest)servletRequest;
-
final
HttpServletResponsehresponse=(HttpServletResponse)servletResponse;
-
Stringuri=hrequest.getRequestURI();
-
logger.debug(
"开始SNA拦截-----------------"
+uri);
-
HttpSessionhttpSession=hrequest.getSession();
-
StringsessionId=httpSession.getId();
-
-
if
(uri.equals(logoutUrl)){
-
logger.debug(
"removesessionmap:"
+sessionId);
-
-
getCache().addOrDecr(
"userCount"
,
1
);
-
getCache().remove(sessionId);
-
}
else
{
-
Stringcookiesessionid=getSessionIdFromCookie(hrequest,hresponse);
-
if
(!sessionId.equals(cookiesessionid)){
-
createCookie(sessionId,hresponse);
-
SessionMapsessionMap=getSessionMap(cookiesessionid);
-
if
(sessionMap!=
null
){
-
logger.debug(
"failover--------sessionid:"
+sessionId+
"cookiesessionid:"
+cookiesessionid);
-
initialHttpSession(sessionMap,httpSession);
-
cache.remove(cookiesessionid);
-
}
-
}
-
}
-
filterChain.doFilter(hrequest,hresponse);
-
}
利用HttpSessionAttributeListener监听httpsession的属性变化,同步到memecached中的sessionmap。
-
public
void
attributeAdded(HttpSessionBindingEventevent){
-
HttpSessionhttpSession=event.getSession();
-
StringattrName=event.getName();
-
ObjectattrValue=event.getValue();
-
StringsessionId=httpSession.getId();
-
logger.debug(
"attributeAddedsessionId:"
+sessionId+
"name:"
+attrName+
",value:"
+attrValue);
-
SessionMapsessionMap=getSessionMap(sessionId);
-
if
(sessionMap==
null
){
-
-
getCache().addOrIncr(
"userCount"
,
1
);
-
sessionMap=
new
SessionMap();
-
}
-
logger.debug(
"name:"
+attrName+
",value:"
+attrValue);
-
sessionMap.put(attrName,attrValue);
-
getCache().put(sessionId,sessionMap);
-
}
-
-
public
void
attributeRemoved(HttpSessionBindingEventevent){
-
HttpSessionhttpSession=event.getSession();
-
-
StringattrName=event.getName();
-
StringsessionId=httpSession.getId();
-
logger.debug(
"attributeRemovedsessionId:"
+sessionId+
"name:"
+attrName);
-
SessionMapsessionMap=getSessionMap(sessionId);
-
if
(sessionMap!=
null
){
-
logger.debug(
"remove:"
+attrName);
-
sessionMap.remove(attrName);
-
getCache().put(sessionId,sessionMap);
-
}
-
}
-
-
public
void
attributeReplaced(HttpSessionBindingEventevent){
-
attributeAdded(event);
-
}
利用HttpSessionListener,sessionDestroyed事件时根据sessionid删除memcached里的sessionMap(如果存在)。不再担心httpsession的过期问题。
-
public
void
sessionDestroyed(HttpSessionEventevent){
-
HttpSessionhttpSession=event.getSession();
-
StringsessionId=httpSession.getId();
-
logger.debug(
"sessionRemovedsessionId:"
+sessionId);
-
SessionMapsessionMap=getSessionMap(sessionId);
-
if
(sessionMap!=
null
){
-
logger.debug(
"removesessionmap:"
+sessionId);
-
-
getCache().addOrDecr(
"userCount"
,
1
);
-
getCache().remove(sessionId);
-
}
-
}
三、 文件保存的处理
和缓存类似,采用集中式的文件服务。对于linux,采用nfs。参考文档http://linux.vbird.org/linux_server/0330nfs.php#What_NFS_perm
。关键在于对权限的分配。
应用程序本身不用修改。
分享到:
相关推荐
Arcus 是一个基于 memcached 的云缓存,由 NAVER Corp 公司开发。 arcus-memcached 经过大幅度的修改,可以支持 NAVER 的功能和性能要求。Arcus 支持多种数据机构 (List, Set, B tree),除了支持基本的memcached ...
Tomcat基于memcached的session保持-nginx反代
C#使用memCached实现缓存 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。...
Memcached Go Queue, 简称mgq, 是一个用Go语言写的,基于memcached协议的消息队列。其父亲mcq是最早应用于weibo的基础消息中间件,有着高性能,解耦的优点,使得其广泛应用于微博
tomcat中Nginx+memcached实现session共享 所需要的jar包
公司要求组织一个基于Java的memcached培训,整理了这个文档。里面有4个文件,包括memcached部署,memcached培训,监控工具memcache-top安装和daemontools安装。文档是基于word2013的,打不开的话,右键--属性--解锁
在分析了几种典型的词典机制优缺点的基础上,提出一种基于memcached的动态四字双向词典机制。该词典机制有效减少了文章分词过程中对词典的访问次数,同时具有维护方便及快速添加和删除临时词等优点,适合在Web上采用...
memcached实现集群的session共享问题,处理集群服务器情况下,memcached的session共享解决方案
j2ee项目使用filter和memcached实现session服务器
里面包括了Memcached的相关实例程序,提供给大家分享
对于 Memcached 来说,本身是集中式的缓存系统,要搞多节点分布,只能通过客户端实现。Memcached 的分布算法一般有两种选择:
Nginx+Tomcat+Memcached实现tomcat集群和session共享 nginx配置
在终端(也即cmd命令界面)下输入 ‘c:\memcached\memcached.exe -d install’ 安装 3. 再输入: ‘c:\memcached\memcached.exe -d start’ 启动。NOTE: 以后memcached将作为windows的一个服务每次开机时自动启动...
memcached, libevent, MemCachedClient
Memcached使用实例源码(基于.net),基于.net的mem dll以及源码,memcached使用,优缺点简介ppt
memcached 64位 window memcached 64位 window memcached 64位 window
为了使web应用能使用saas模式的大规模访问,必须实现应用的集群部署.要实现集群部署主要需要实现session共享机制,使得多台应用服务器之间会话统一, tomcat等多数服务都采用了session复制技术实现session的共享
NULL 博文链接:https://guazi.iteye.com/blog/1071646
nginx+tomcat8+memcached session共享所需jar包 直接放到tomcat/lib下即可
tomcat memcached nginx 实现session共享,实现登录登录