问题:在项目里面,因为承载的压力比较大,所以就会产生一个问题:Session是怎么同步的.
如果只使用服务器提供的原生Session是很明显没办法满足需求的.
比如说:用户的第一次请求在服务器A,但是第二次请求在服务器B.用户的Session信息就会全部丢失了.
有些容器提供了原生的Session同步,自带同一台服务器的Session会同步到其他.在一个集群里面,应用的并不多.
为什么?性能有问题,而且实现起来复杂(服务器多了以后就会变复杂).
前置知识:Session的实现,比如说SessionID(一般是UUID),写到库里面,传递到前台,前台在访问的时候上传这个TOKEN,服务端拿到TOKEN,就根据TOKEN拿到用户信息
好了,现在问题描述完了.来讲一下常用的几种实现方式.
1.粘性session
顾名思义,就是用户访问了一台服务器存了Session以后,用户以后访问就只能访问这台服务器了.
优:实现简单,原生的Session不需要改变
缺:服务器宕机,用户到第二台服务器上Session就会丢失
使用场景:Session不重要,服务器宕机的可能性比较小.
2.服务器Session复制.
顾名思义,用户登录服务器A,会在集群之间同步用户的Session
优:容错性.
缺:增加通信成本 Session量大会造成网络堵塞
3.Session共享机制
这个有一个前提,有分布式缓存方案,而且必须是有集群的
这个也分为两种或实现
3.1.粘性Session处理方式
不同的tomcat指定访问不同的缓存,缓存之间信息同步,(主从?哨兵?).
用户访问在tomcat创建一个Session,然后被分到memcache,读写都在tomcat上面.当tomcat挂掉以后,集群讲用户访问定位在备份tomcat上面,然后根据Session或者说TOKEN找Session.找不到在去memcache上找.(顺便说一句,我遇到的这个问题就是用类似于这种方式实现的)
3.2.非粘性Session处理方式
原理:memcached做主从复制,写入session都往从memcached服务上写,读取都从主memcached读取,tomcat本身不存储session.
4.session持久化到数据库
这个不用多说,显然增加数据库开销,但是实现起来也简单.而且进行了持久化,数据很好保存.
可以说除了数据库开销以外,没啥缺点了.但是这个对数据库开销的缺点基本上是没办法容忍了.
我的解决办法:
1.用户登录成功以后生成一个UUID.作为TOKEN.
2.把token传到前台,并给cookie设置一个有效期间(这里要注意,有效期是指用户最后一次登录 + 有效期就到期)
3.根据TOKEN 和 user的序列化对象放入Redis
3.1拿取的时候就是根据TOKEN来拿的
4.每次登录,就重新设置cookie和token的有效期(可以用expire设置有效期)防止redis库数据冗余.