笔记簿
ᴄᴏᴅɪɴɢ ɪs ᴀʀᴛ
首页
关于
搜索
登录
注册
服务器集群session共享 - 分布式系统该如何做好单点登陆
假设网站部署在N台服务器上,可能是tomcat集群或者nginx集群,在集群之前有一个负载均衡服务器,使得用户对网站的访问会均衡地访问到服务器集群的各个节点上。 现在A用户开始访问网站,假设分配到b服务器上,那么如果A用户在session生命周期内,再次访问网站(用户在访问的过程中是随机切换到其他服务器),如何获得他的session呢?(因为可能会分配到其他服务器上,或者如何记得之前分配在哪个服务器上?) 这就是服务器集群session共享问题。 **解决方案:** #### 1. tomcat session复制 tomcat本身自带session复制功能,开启server.xml中的`cluster`节点,做相应的配置即可。参见Apache Tomcat 8 (8.0.26)。tomcat本身的session复制功能并不好用,官方文档也说方式只适合小集群: This works great for smaller cluster but we don't recommend it for larger clusters(a lot of Tomcat nodes). 并且tomcat本身并发性能也并不太好。这种方式更加适合于对并发要求不高的小规模集群。 #### 2. redis存储session 这种方案可能是用得最多的一种 直接配置tomcat的session管理,session直接让redis管理 主要的配置是在 修改tomcat的context.xml ```xml
``` 所有session都存在redis(redis集群)中,无论访问哪台服务器最终都会把session保存在redis中,然而redis集群是如何保证各个结点的数据一致性,对于这个需求是黑匣子,不必关心。 #### 3. session cookie化 把原来存储在服务器磁盘上的session数据存储到客户端的cookie中去。 这样子,就不需要涉及到数据共享了。a客户端请求的时候,原来生成在服务器的数据生成到浏览器的cookie中,根据cookie中的数据识别用户。 这样子,在多台服务器负载均衡的情况下,即便第一秒请求是a服务器,第二秒请求是b服务器,都不需要管哪台服务器了。反正都是读取客户端上的cookie数据。 一般是把session数据按照自己定义的加密规则,加密后后存在cookie中。 数据保存在cookie中这种做法有好处,也有坏处。 好处是服务器的压力减小了,因为session数据不存在服务器磁盘上。根本就不会出现session读取不到的问题。 带来的弊端是: 网络请求占用很多。每次请求时,客户端都要通过cookie发送session数据给服务器。 另外,浏览器对cookie的大小存在限制。每个浏览器限制是不同的。 * Firefox和Safari允许cookie多达4097个字节,包括名(name)、值(value)和等号。 * Opera允许cookie多达4096个字节,包括:名(name)、值(value)和等号。 * Internet Explorer允许cookie多达4095个字节,包括:名(name)、值(value)和等号。 所以这种方案不适合**高访问量**的情况下,因为高访问量的情况下,每次请求浏览器都要发送session数据给服务器。一般一个cookie大小2k的样子。 **要占用很多带宽了(服务器购买带宽是一个很大费用),成本增高**。归纳为带宽性能,速度问题。 存储到cookie中去,第二方面是安全问题:把session数据放到客户端,一般session中存的都是重要性数据(帐号、昵称、用户id等),会存在安全问题。 了解到,淘宝以前用过这种方式,把session数据存储到cookie中,根据cookie来识别用户。 #### 4. 粘性session 该种方式下,当用户发出第一个request后,被分配到某个节点,并记录该节点的jvm路由,以后该用户的所有request都会被绑定到这个jvm路由,用户只会与该server发生交互,这种策略称为粘性session。 优点是响应速度快,多个节点之间无须通信。 缺点是某个节点down掉后,用户就丢失了session。 #### 5. 不使用session HTTP本身就是无状态的,应用服务器为了跟踪用户状态而强行加入了session。服务器为了保存用户状态就需要做额外的工作。 于是乎,Token-based的身份校验因其伸缩性而广受欢迎。在用户登录后,服务器返回一个token给用户,用户后续的请求都需要附带此token,服务器会校验该token来判断用户身份,进而完成具体业务。