SpringSession 初步了解
来源:互联网 发布:大麦户源码下载 编辑:程序博客网 时间:2024/05/01 22:45
为支持项目的分包部署,简化分包环境下的SSO和Session共享,首次在架构中引入了SpringSession的SNA组件,为此项目组进行了不少工作,包括:Spring平台从原来的Spring2.5.6一跃到Spring4,同时引入了SpringSession所必须的SpringData和对Redis的支持。
SpringSession的原理其实很简单:就是通过一个站在最顶端的Filter,将传统的HttpServletRequest和HttpServletResponse进行包装,重载getSession方式,将获取和存储Session的相关操作,转义到保存或者从Redis中提取信息。由于Redis支持Map形式的数据类型,因此比较适合存储Session这类数据,选用Redis作为集中缓存也就顺理成章了。
从Redis3.0版本开始,Redis内存库自身已经支持集群管理,我们可以方便地创建出一个多主多备的Redis集群环境。并且SpringSession目前的版本已经是1.3.1,从版本上看,也具备使用价值了。
前段时间为检验SpringSession的性能,进行了几轮对比压力测试,发现使用SpringSession的分包环境比较慢,我们非常重视这件事情,要分析和性能调优,首先要弄清楚SpringSession到底是怎么做的。只能通过读源码了。真的很佩服Spring的设计师,程序还是一如既往的“复杂”,但结构非常清晰,设计师还是非常有水准的。通过源码和Redis的活动监控,也发现了SpringSession处理的一些端倪。
SpringSession对Redis的封装完全基于Jedis,连接池也是使用的Apache的Commons-Pool,借助SpringData进行统一封装。使用了Spring惯用的FilterProxy机制,使用一个Filter完成了对Request,Response的Wrap。并在Wrap中完成Session信息向Redis的双向转移。
为了提高效率,SpringSession中对Session做了特殊的处理:
1) 每次从Redis中获取信息以后,在RequestContext中进行了缓存,因此一次请求只需从Redis中读取一次。
2) 对于Session信息的保存时机,SpringSession提供了两种方案供你选择:Immediate和ON_SAVE,分别为马上保存和批量保存。
3) 对于保存的信息,SpringSession进行的增量处理,即在Session的本地缓存中,包有一个记录Session变化的Delta,每次进行保存时只需要处理变化的量。
还有一个棘手的问题是:关于超时如何处理,采用SpringSession机制后,Web中的一些规范,如SessionListner机制将会变得很复杂,因此SpringSession为此做了很多的工作。
1) 为保存在Redis中的Session信息设置了超时时间,为了保证这种机制的顺利进行,除了Session信息,SpringSession在Redis中还维持着多个key和集合:包括:单独增加了一个key,记录Session的超时时间,可以借助Redis的通知机制完成;为了保证超时的信息能及时删除,SpringSession还位置着一个到期的Collection,定时检查这个集合,主动进行Session超时处理。这部分比较复杂,这里不多讲了。
2) 每次请求,SpringSession都会更新Session和上述附件信息的超时时间,显得非常啰嗦
性能差的原因会不会是Redis访问太频繁造成的呢?我们单独跟踪了一个请求,发现SpringSession采用增量方式进行了两次保存 HMSet,通过仔细分析代码,发现在ResponseFlush 之前,为保证Response中保持Cookie信息,执行了一次增量保存,最后Filter执行完了后,在finally方法中又执行了一次。分析程序发现每执行一次,要访问Redis多次,达到保存、更新和设置超时时间的目的。我们遇到的一个问题是:根据SpringSession的保存策略,只要Delta中没有变更信息,系统不再保存,进而也没有相关的设置超时时间的动作,为什么我们系统在Finally中也进行了保存呢?根据Redis的监控结果,发现平台中的一个Filter在执行完DoFilter后,在Session中设置了一个值,引起了Delta的变化,从而触发了finally方法中的save操作
要使用SpringSession+Redis,有几件事情要注意:
1) 应该在一个网段中,保证网络的带宽
2) 需要修改程序,将Session中的信息变得简单,最好只保留用户和授权信息
3) 作为信息传递的Session信息,使用完毕后,尽快删除
4) 系统中的Filter中蛮实用Session时要注意,尽量让SpringSession保存一次Session信息。
5) 有可能的话,对SpringSession的超时机制进行优化,减少不必要的处理。这个相对麻烦一些,我们现在只能通过硬编码的方式,没有一种优雅的替换策略。
- SpringSession 初步了解
- SpringSession教程
- SPRING 了解初步
- Jawe的初步了解
- Jawe的初步了解
- 初步了解osworkflow designer
- (二)初步了解
- 初步了解Oracle
- 初步了解CSS
- 初步了解CSS3
- Felix?OSGi? -初步了解
- 环境变量初步了解
- 初步了解接口测试
- skyeye初步了解
- Linux管道初步了解
- opencms初步了解
- 初步了解com
- Linux管道初步了解
- 一叶障目, 不见泰山------要对整个数据流有非常清晰的认识,避免走入死胡同!
- 百炼OJ:4146:数字方格
- IEnumerable和IEnumerator 详解
- 安装 Ubuntu 17.04后的一些简单配置
- Redis 和 Memcached 的区别
- SpringSession 初步了解
- 复杂网络上的社会激励: 从应用到理论
- Codeforces 805C (贪心)
- 1470: 单词反转
- C#属性和索引器
- shell case语句及函数
- shell 正则表达式
- HDU2546饭卡 01背包入门
- [转]AXI4与AXI3区别