【基于唯品会MP平台】集群环境下session共享技术方案及分布式单点登录

背景

传统的B/S架构的系统中,一般为单点部署,并不存在集群,所以也不存在session丢失的问题。那么,由于单点部署一旦宕机,无法保证系统可用性,那我们就想到把它扩展为多台服务器部署,这样既保证了系统的可用性,又降低了单点的压力。但是,在集群环境下,原来的application级别的session,由于只局限于单点容器中,并不能保证可见,所以必然会造成用户会话状态的丢失。如下图:

【基于唯品会MP平台】集群环境下session共享技术方案及分布式单点登录_第1张图片

解决方案

cookie存储

cookie存储这种方式很简单,因为cookie特点是在server端生成,保存在client端。这样我们就可以,在创建cookie的时候,把user的相关信息存储到cookie里面。因为cookie默认生命周期就是关闭浏览器即消失。另外,cookie是通过http header传输的,我们可以在server端拦截,根据cookie的name获取user的信息。

缺点:

1,cookie在浏览器中存储,存在安全隐患。

2,cookie存储数据大小为4K,浏览器最多保存300个cookie限制。

3,每一次请求都会带着cookie,cookie中值过大会增加网络开销。

结论:内网系统可以使用,互联网中不推荐。

【基于唯品会MP平台】集群环境下session共享技术方案及分布式单点登录_第2张图片

session广播

其原理就是,Tomcat服务器会把自己存储的session广播同步给集群中其他的节点。没什么难点,给出配置如下:

【基于唯品会MP平台】集群环境下session共享技术方案及分布式单点登录_第3张图片

缺点:1,首先session广播是要通过网络在集群中的各个Tomcat节点上传输,本身Tomcat就是要处理外部请求,这样占用了服务的带宽资源,会使Tomcat处理能力下降。

          2,传输过后,各节点也要有replication,所以对磁盘IO也增加了压力。

         3,由于有网络传输和节点sync,所以很有可能在下一次请求到来时,没有做完这两件事,直接导致找不到session。

结论:节点不多时,可以作为临时方案,但不推荐。

【基于唯品会MP平台】集群环境下session共享技术方案及分布式单点登录_第4张图片

ip_hash

ip hash,顾名思义是根据请求client端的ip做hash运算再对服务组取模运算,得到的就是routeNo。现有的web服务器有支持这种路由算法,如nginx,apache+JK(类似,但它其实为粘性session Sticky)等。

eg:

                 upstream backserver {
                     ip_hash;
                  server 192.168.0.14:88;
                  server 192.168.0.15:80;
                }

缺点:

1,这种负载均衡策略,并不能很均衡的在集群中分配流量,导致流量可能会集中在某一台服务器上面。

2,一旦出现某一节点宕机的情况,那这个节点的会话就会丢失。

结论:流量不是特别大的项目,可以用。

【基于唯品会MP平台】集群环境下session共享技术方案及分布式单点登录_第5张图片

缓存共享

缓存共享的方式,是通过外部的缓存或存储器去解决session对于各个application的可见性,统一性。一般,考虑性能,稳定性方面,会选择Redis或memcache来保存user信息,根据相应的规则生成一串唯一的安全的摘要串作为KEY。而在这个KEY也叫token或被种到cookie里面,请求会带着这个token来保持会话的状态。

这里多说一嘴,其中tomcat 8.x开始新增了相应的标签空间,可以直接集成memcache了。

eg:

            unpackWARs="true" autoDeploy="true">
       
                   memcachedNodes="n1:192.168.238.250:11211,n2:192.168.238.251:11211"
         failoverNodes="n2"
         requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
         transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"/>
     

     

缺点:

1,压力在于你的缓存服务,因为所有的用户信息都会被缓存在你的Redis里。

2,系统有一定复杂性。

结论:可用性,扩展性都不错,推荐。

【基于唯品会MP平台】集群环境下session共享技术方案及分布式单点登录_第6张图片

其他

其他对于session共享的解决方案,也有,例如:商业版的session存储盒子(可以把它看成一个存储器,独立部署一个服务器上面。),使用硬件F5做粘性会话,成本太高,后期也不好维护等等。其他方式不是特别合适,所以不做一一介绍。

单点登录

单点登录简称为 SSO。其意思就是,在一个系统或者网站中登录以后,再点击跳转到另一个或者多个系统或者网站,可以直接获取到用户的会话信息,不用再重复登录。

单点登录在分布式系统架构中,都是单独分离出来,作为独立项目和服务进行部署和维护的。可以提供相应的RPC协议,也可以提供HTTP协议。

单点登录主要的难点有两点:1,session的共享(我们上面已经讨论过)。2,cookie的跨域。

我们下面来看看什么是cookie跨域,怎么样才能cookie跨域。

因为cookie是在服务端生成的,保存在浏览器端,只有浏览器在访问相应的域名(在服务端种cookie时,绑定的域名),所以你的cookie就只能在当前域名下有效。

一般好多公司都会使用子域名,这样就可以把cookie种到主域名下,那各个的子域名下都会取到这个cookie。

【基于唯品会MP平台】集群环境下session共享技术方案及分布式单点登录_第7张图片

当然,还有那种,域名完全不相同的情况,解决的方案也有好多种。比如抛弃cookie,转为URL参数加token,乐视云计算官网以前就是这样解决的。再比如在当前页面用js创建一个iframe,把当前域A的cookie作为参数,用iframe的属性src重定向的方式调用B域的接口,B域拿到A的cookie再种下来。再比如也可利用jsonp($getJson)强行跨域,后端在相应处理。还有耶鲁大学的开源框架cas,支持mysql,redis等,也集成了shiro,但是对调用方的侵入比较严重,设计还可以。

综上,解决集群分布式环境的会话问题,要充分的了解session和cookie的机制,还要做好分布式场景中的系统界限划分。

你可能感兴趣的:(技术,redis,Java,session)