集群环境下的Session处理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了集群环境下的Session处理相关的知识,希望对你有一定的参考价值。

参考技术A 在单台服务器情况下session处理比较简单,一旦到了集群环境中,我们就必须考虑用户和会话的问题,如果不加处理的话,一旦后端IP轮询切换,会话cookies找不到session,会话就中断了。在此情景下,通常有以下5种解决方案。

将每一个用户和后端服务器绑定,这样用户的会话就会一直落在同一台服务器上,这是成本最小的解决方案,只需要修改nginx服务器的配置即可。如果是在比较老的架构上,推荐这种改造方案。

这种解决解决方案也存在局限性,比如某台服务器挂了切换到另一台服务器,对应的会话也就丢了。还有另外一个问题,如果前端用了CDN的话,客户端IP变化的频率可能是很高的,有可能一个小时或更短时间内就变一次,这在校园网的网络环境下很容易产生这种情况。

顾名思义,Session复制就是让集群里的每台服务器都存储整个集群所有服务器上的全部session。这样一旦某台服务器挂了,用户切换到其他服务器上也能访问到一样的session数据。这种解决方案不好的地方在于进行session复制需要额外的网络开销和系统资源,当服务器较多或session中存储的数据量大的时候,这个问题尤为明显。

Session复制本身的操作是比较复杂,但是对于服务器来说,配置比较简单,但性能是个很大的问题。当集群中服务器数量大于两台时就比较吃力了,总之这是一种比较早期时候的解决方案。

sticky方案和方案1类似,但是sticky能把会话死死地粘滞在其中一台服务器上,算是对方案1的补充,可以避免在CDN网络波动下的IP冲突造成的会话丢失。但是依然无法解决服务器挂掉导致会话丢失的问题。

基于Redis等NoSQL的session集中存储方案,是目前最流行的解决方案,早期用mysql来存储。引入Redis的方案除了会增加系统复杂度外,依然还有以下几个问题:

使用纯cookie,不使用session,天然分布式。存在问题:

需要注意的是,如果应用需要做“禁止同时登录”的需求时,用Cookie的话解决起来会麻烦很多。

另外可以把cookie换成token等方式验证用户,每次请求带上token作为会话凭据。

集群/分布式环境下,Session处理策略

前言

       在搭建完集群环境后,不得不考虑的一个问题就是用户访问产生的session如何处理。如果不做任何处理的话,用户将出现频繁登录的现象。比如集中中存在A、B两台服务器,用户在第一次访问网站是,Nginx通过其负载均衡机制将用户请求转发到A服务器,这时A服务器就会给用户创建一个Session。当用户第二次发送请求时,Nginx将其负载均衡到B服务器,而这时候B服务器并不存在Session,所以就会将用户导航到登录页面。这样的话,肯定会大大降低用户的体验度,导致用户黏度下降。

       我们应当对产生的Session进行处理,通过一些处理策略,来保证用户的体验度

下边,我将分析5中Session处理策略,并分析其优劣性。

第一种:粘性Session

原理:粘性Session是指将用户锁定到某一服务器上,比如上面讲的Demo,用户第一次请求时,Nginx将用户请求转发到了A服务器上,如果Nginx设置了粘性Session的话,那么用户以后的每次请求都会转发到A服务器。这样做,就相当于把用户和A服务器粘到了一起,这就是粘性的Session机制。

优点:简单,不需要对Session做任何处理

缺点:缺乏容错性,如果当前访问的服务器发生故障,用户被转移到第二个服务器上是,它的Session信息都将失效。

使用场景:发生故障后对客户产生的影响较小;服务器发生故障时小概率事件。

实现方式:以Nginx为例,在upstream模块配置ip_hash属性即可实现粘性Session。

upstream mycluster
    #这里添加的是上面启动好的两台Tomcat服务器
    ip_hash;#粘性Session
     server 192.168.22.229:8080 weight=1;
     server 192.168.22.230:8080 weight=1;

第二种:服务器Session复制

原理:任何一个服务器上的Session发生改变(增删改),该节点会把这个Session的所有内容序列化,然后广播给所有其他节点,不管其他服务器需不需要Session,以此来保证Session同步。

优点:可容错,各个服务器间Session能够实时响应。

缺点:会对网络负荷造成一定压力,如果Session量大的话,可能会造成网络堵塞,拖慢服务器性能。

实现方式:

1、设置Tomcat,server.xml开启Tomcat集群功能


Address:填写本机IP即可,设置端口号,预防端口冲突。

2、在应用里增加信息:通知应用当前处于集群环境中,支持分布式。

在web.xml中添加选项:<distributable/>


第三种:Session共享

使用分布式缓存方案,比如memcached、Redis,但是要求Memcached或Redis必须是集群。

使用Session共享,也分为两种机制,如下:

1、粘性Session处理方式

原理:不同的Tomcat指定访问不同的主memcached。多个memcached之间信息是同步的,能主从备份和高可用。用户访问时,首先在Tomcat中创建Session,然后将Session复制一份放到它对应的memcached上。memcached只起到备份左右,读写都在Tomcat上。当某一个Tomcat挂掉之后,集群将用户的访问定位到备Tomcat上,然后根据cookie中存储的SessionID找到Session,找不到时,再去相应的memcached上去寻找Session,找到之后将其复制到Tomcat上。


       

2、非粘性Session处理方式

原理:memcached做主从复制,写入Session在从memcached服务器上,读取Session从主memcached,Tomcat本身不存储Session。

优点:可容错,Session实时响应。

实现方式:用开源的msm插件解决Tomcat之间的Session共享:Memcached_Session_Manager(MSM)

a. 复制相关jar包到tomcat/lib 目录下

JAVA memcached客户端:spymemcached.jar

msm项目相关的jar包:

1. 核心包,memcached-session-manager-version.jar
2. Tomcat版本对应的jar包:memcached-session-manager-tctomcat-version-version.jar

序列化工具包:可选kryo,javolution,xstream等,不设置时使用jdk默认序列化。

b. 配置Context.xml ,加入处理Session的Manager

粘性模式配置: 

非粘性配置: 


第四种:Session持久化到数据库

原理:拿一个数据库专门用来存储Session信息,保证Session的持久化。

优点:服务器出现问题,Session不会丢失。

缺点:如果网站的访问量很大,把Session存储到数据库中,会对数据库造成很大压力,还需要增加额外的开销,维护数据库。


第五种:Terracotta实现Session复制

原理:Terracotta的基本原理是对于集群间共享的数据,在当一个节点发生变化的时候,Terracotta只把变化的部分发送给Terracotta服务器,然后由服务器把它转发给真正需要这个数据的节点。这种方案可以看成是对第二种方案的优化。


优点:这样对网络的压力非常小,各个节点也不必浪费CPU时间和内存进行大量的序列化操作。把这种集群间数据共享的机制应用在Session同步上,既避免了对数据库的依赖,又能达到负载均衡和灾难恢复的效果。

总结

       以上就是在集群或者分布式环境下,Session处理的5中策略。其中就应用广泛性而言,第三种方式,也就是基于第三方缓存框架共享Session,应用的最为广泛,无论是效率还是扩展性都还可以。而Terracotta作为一个JVM级的开源集群框架,不仅仅提供HTTP Session复制,它还能做分布式缓存,POJO群集,跨越群集的JVM来实现分布式应用程序协调等。

Ps:原文地址http://blog.csdn.net/u010028869/article/details/50773174

以上是关于集群环境下的Session处理的主要内容,如果未能解决你的问题,请参考以下文章

集群/分布式环境下5种session处理策略

集群/分布式环境下5种session处理策略

集群/分布式环境下5种session处理策略

Redis集群环境下的键值空间监听事件实现方案

架构师之路集群/分布式环境下5种session处理策略

集群/分布式环境下,Session处理策略