-
Notifications
You must be signed in to change notification settings - Fork 626
分布式系统下Session管理
当用户初次请求应用程序的 Web 页面时,Web服务器将自动为用户创建一个Session对象,存储用户的相关信息,如用户的登录信息,以便多次请求能够定位到同一个上下文。
随着网站的功能和用户越来越多,单机器服务部署的Web应用已经不能再支持了。这时候就需要优化或调整目前的架构,具体怎么优化,或先优化哪部分,这取决于网站的具体情况。 根据使用情况:
- 如果数据库压力大,则就可以设置读写分离、分库分表,对于分库分表,有垂直划分(可以简单的理解为按业务功能划分),还有水平划分(如用户表数据量很多,就可以按一定的规则分表设计,表结构仍然是相同的)。
- 如果是Web应用服务器压力大,可以增加一台服务部署应用,即从单台服务变为集群。变为集群后,用户访问网站,到底是选择哪一台服务器呢?这就需要在应用服务器前增加负载均衡设备来解决。
针对对第二种情况,就会出现我们即将要讨论的session 管理的问题:分布式系统下的Session。
当一个带有会话表示的Http请求到Web服务器后,需要在请求中的处理过程中找到session数据。而问题就在于,session是保存在单机上的。假设我们有应用A和应用B,现在一位用户第一次访问网站,session数据保存在应用A中。如果我们不做处理,怎么保障接下来的请求每次都请求到应用A呢?如请求到了应用B中,就会发现没有这位用户的session数据,这绝对是不能容忍的。
解决方案有Session Stick,Session复制,Session集中管理,基于Cookie管理,下面一一说明。
在单机情况,session保存在单机上,请求也是到这台单机上,不会有问题。变成多台后,如果能保障每次请求都到同一台服务,那就和单机一样了。 这需要在负载均衡设备上修改(通常利用一个反向代理服务器,如nginx。用hash算法来将同一个请求的IP的落在同一台服务器上,所以这种方法又称为反向代理hash一致法)。
这种方式会有一下问题:
- 如果某一台服务器宕机或重启,那么这台服务器上的session数据就丢失了,如果session数据中还有登录状态信息,那么用户需要重新登录。
- 负载均衡要处理具体的session到服务器的映射。
Session复制顾名思义,就是每台应用服务,都保存会话session数据,一般的应用容器都支持。与Session Stick相比,sessioon复制对负载均衡 没有太多的要求。
不过这个方案还是有缺点:
- 同步session数据带来都网络开销。只要session数据变化,就需要同步到所有机器上,机器越多,网络开销越大。
- 由于每台服务器都保存session数据,如果集群的session数据很多,比如90万人在访问网站,每台机器用于保存session数据的内容占用很严重。
这个方案是靠应用容器来完成,并不依赖应用,如果应用服务数量并不是很多,可以考虑。
这个也很好理解,再加一台服务,专门来管理session数据,每台应用服务都从专门的session管理服务中取会话session数据。可以使用数据库,NOSQL数据库等。和Session复制相比,减少了每台应用服务的内存使用,同步session带来的网络开销问题。
但还是有缺点:
- 读写session引入了网络操作,相对于本机读写session,带来了延时和不稳定性。
- 如果Session集中服务有问题,会影响应用。
最后一个是基于Cookie管理,我们把session数据存放在cookie中,然后请求过来后,从cookie中获取session数据。与集中管理相比,这个方案并不依赖外部 的存储系统,不会有读写session数据带来的网络操作延时和不稳定性。 但依然有缺点:
- Cookie有长度限制,这会影响session数据的长度。
- 安全性。session数据本来存储在服务端的,而这个方案是让session数据转到外部网络或客户端中,所以会有安全性问题。不过可以对写入Cookie的session 数据做加密。
- 带宽消耗。由于每次Http请求都携带了session数据,带宽当然也会增加一点。
- 性能消耗。每次Http请求和响应都带有Session数据,对于Web服务器来说,在同样的处理情况下,响应的结果输出越少,支持的并发请求越多。
现在常见的解决方式就是Session集中管理,也就是本门课程老师讲解的了。
目录