系统要集群,使用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
。关键在于对权限的分配。
应用程序本身不用修改。
分享到:
相关推荐
【资源概览】 高分项目 基于STM32F103单片机的无线测距系统源代码+项目资料齐全+教程文档.zip高分项目 基于STM32F103单片机的无线测距系统源代码+项目资料齐全+教程文档.zip高分项目 基于STM32F103单片机的无线测距系统源代码+项目资料齐全+教程文档.zip 【资源说明】 高分项目源码:此资源是在校高分项目的完整源代码,经过导师的悉心指导与认可,答辩评审得分高达95分,项目的质量与深度有保障。 测试运行成功:所有的项目代码在上传前都经过了严格的测试,确保在功能上完全符合预期,您可以放心下载并使用。 适用人群广泛:该项目不仅适合计算机相关专业(如电子信息、物联网、通信工程、自动化等)的在校学生和老师,还可以作为毕业设计、课程设计、作业或项目初期立项的演示材料。对于希望进阶学习的小白来说,同样是一个极佳的学习资源。 代码灵活性高:如果您具备一定的编程基础,可以在此代码基础上进行个性化的修改,以实现更多功能。当然,直接用于毕业设计、课程设计或作业也是完全可行的。 欢迎下载,与我一起交流学习,共同进步!
java八股文,"Java八股文"通常指的是在面试Java开发者时经常被问到的一系列标准问题,这些问题往往是技术面试中的基础部分,用来评估应聘者对Java编程语言和Java虚拟机(JVM)的理解程度。这些问题的答案往往模式化,因此被称为“八股文”。虽然这个词汇带有一定的贬义,但是这些问题却是面试中不可或缺的一部分,因为它们能够快速地检验应聘者的基本技能和理论知识。
东北大学本科毕业设计 论文latex模板 2019 关于东北大学本科毕业设计论文的LaTeX模板,您可以参考以下两个资源: 1. **Acytoo/neu_bachelor_thesis_template**: 这个模板是修改自一位学长的模板,以适应东北大学最新的要求。它使用GBT7714-2005参考文献标准,并提供了详细的安装和使用说明。您需要使用xelatex进行编译,并可能需要手动安装参考文献的标准。此外,如果您使用的是VSCode编辑器,可以参考提供的VSCode配置。 2. **tzaiyang/NEUBachelorThesis**: 这个模板同样适用于东北大学本科生毕业论文。它提供了详细的VSCode配置,包括快捷键设置和texcount bug修复(仅限Windows用户)。此外,还提供了如何插入公式、图片和三线表的说明,以及如何引用参考文献的方法。 您可以根据自己的需求和喜好选择其中一个模板。如果您对LaTeX不熟悉,建议先学习一些基础知识,以便更好地使用这些模板。祝您毕业设计顺利!
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
STM32串口通信大纲---适用于初学者 I. 引言 学习背景与串口通信的重要性 简述本文目的与主要内容 II. STM32里的串口通信 基本概念与功能介绍 USART及STM32内置串口 全双工通信与异步时钟控制 接收/发送逻辑结构 III. 串口配置 选择合适的串口资源(USART1/2/3) 参数设置:波特率、位数、校验、停止位 GPIO配置:TX/RX引脚驱动方式 IV. 串口发送与接收 发送数据流程 设置TDR与发送移位寄存器 检测TXE标志位 数据移位与持续发送 接收数据流程 配置RX输入模式 读取RDR与RXNE标志 字节数据接收 V. 实现方式 不使用中断的简单示例 利用中断接收数据 查询中断状态 中断服务程序处理数据
基于opencv和深度学习的手写计算器.zip
【资源概览】 高分项目 基于STM32单片机和Android的智能蓝牙点餐系统源代码+项目资料齐全+教程文档.zip高分项目 基于STM32单片机和Android的智能蓝牙点餐系统源代码+项目资料齐全+教程文档.zip高分项目 基于STM32单片机和Android的智能蓝牙点餐系统源代码+项目资料齐全+教程文档.zip 【资源说明】 高分项目源码:此资源是在校高分项目的完整源代码,经过导师的悉心指导与认可,答辩评审得分高达95分,项目的质量与深度有保障。 测试运行成功:所有的项目代码在上传前都经过了严格的测试,确保在功能上完全符合预期,您可以放心下载并使用。 适用人群广泛:该项目不仅适合计算机相关专业(如电子信息、物联网、通信工程、自动化等)的在校学生和老师,还可以作为毕业设计、课程设计、作业或项目初期立项的演示材料。对于希望进阶学习的小白来说,同样是一个极佳的学习资源。 代码灵活性高:如果您具备一定的编程基础,可以在此代码基础上进行个性化的修改,以实现更多功能。当然,直接用于毕业设计、课程设计或作业也是完全可行的。 欢迎下载,与我一起交流学习,共同进步!
【资源概览】 高分项目 基于STM32单片机的桌面电磁力时钟摆设计源代码+项目资料齐全+教程文档.zip高分项目 基于STM32单片机的桌面电磁力时钟摆设计源代码+项目资料齐全+教程文档.zip高分项目 基于STM32单片机的桌面电磁力时钟摆设计源代码+项目资料齐全+教程文档.zip 【资源说明】 高分项目源码:此资源是在校高分项目的完整源代码,经过导师的悉心指导与认可,答辩评审得分高达95分,项目的质量与深度有保障。 测试运行成功:所有的项目代码在上传前都经过了严格的测试,确保在功能上完全符合预期,您可以放心下载并使用。 适用人群广泛:该项目不仅适合计算机相关专业(如电子信息、物联网、通信工程、自动化等)的在校学生和老师,还可以作为毕业设计、课程设计、作业或项目初期立项的演示材料。对于希望进阶学习的小白来说,同样是一个极佳的学习资源。 代码灵活性高:如果您具备一定的编程基础,可以在此代码基础上进行个性化的修改,以实现更多功能。当然,直接用于毕业设计、课程设计或作业也是完全可行的。 欢迎下载,与我一起交流学习,共同进步!
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
基于深度学习的手写数字识别.zip
这篇文章的核心内容是关于一种图像去噪算法——非局部均值(Non-Local Means, NLM)算法的快速且开源的实现。以下是文章的主要要点: 算法介绍:文章提出了一种快速且无参数的NLM算法实现,该算法用于去除图像中的噪声。NLM算法由Antoni Buades, Bartomeu Coll和Jean-Michel Morel在2005年引入,因其简单性、出色的视觉效果以及利用自然图像的非局部冗余性而受到广泛欢迎。 算法改进:文章基于线之和的计算来计算块距离,这些线在块移位下是不变的。通过从一个图像数据库中计算NLM的最佳参数(以平均峰值信噪比PSNR为标准),实现了一个无需参数调整的NLM算法。
Hypack 2016、Hypack 2021、Hypack 2022、Hypack 2024 四个版本的完整中文资源,全部完成汉化,汉化完整错误少,全网汉化第一,替换相应版本的资源文件即可。 压缩包含资源文件lngEdit.db和汉化了的lngEdit.exe程序(命名为lngEditChs.exe)
selenium 库和浏览器驱动的安装.rar
预警系统链性态网体系化作战矩阵.txt
基于深度学习的普通话语音识别.zip
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
com.smile.gifmaker.apk
模拟退火算法(Simulated Annealing,SA)是一种基于概率的算法,其灵感来源于固体退火原理。模拟退火算法最早由N. Metropolis等人在1953年提出,随后在1983年由S. Kirkpatrick等人成功地将退火思想引入到组合优化领域。该算法基于物理中固体物质的退火过程与一般组合优化问题之间的相似性,通过赋予搜索过程一种时变且最终趋于零的概率突跳性,从而有效避免陷入局部极小并最终趋于全局最优。 模拟退火算法的基本思想是从某一较高初温出发,伴随温度参数的不断下降,结合概率突跳特性在解空间中随机寻找目标函数的全局最优解。算法的主要步骤如下: 初始化:设置初始温度T(充分大)、初始解状态S(算法迭代的起点)以及每个T值的迭代次数L。 对k=1,...,L进行以下操作: 产生新解S':通过对当前解进行变换(如互换、置换等)产生新解。 计算增量ΔT=C(S')-C(S),其中C(S)为评价函数。 判断新解是否接受:若ΔT<0,则接受S'作为新的当前解;否则以概率exp(-ΔT/T)接受S'作为新的当前解。 如果满足终止条件(如连续若干个新解都没有被接受),则输出当前解
2023年广西中小学生程序设计挑战赛初赛(入门组)试题及答案.pdf
基于深度学习的近红外光谱数据回归分析模型.zip