我们先来看看什么是Session。用户使用网站的服务,基本上需要浏览器和网络服务器之间进行多次交互。HTTP协议本身是无状态的,需要基于HTTP协议的支持会话状态(SessionState)的机制。而这样的机制应该能够让Web服务器从多个独立的HTTP请求中看到“会话”,也就是知道请求来自于哪个会话。具体实现方法是:在会话开始时,分配一个唯一的会话标识符(SessionId),并通过cookie告诉服务器这个标识符,以后每次请求时,浏览器都会带上这个会话标识符告诉Web服务器该请求属于哪个会话。在Web服务器上,每个会话都有一个独立的存储,存储不同会话的信息。如果遇到cookie被禁用的情况,一般的做法是将这个sessionID放在URL的参数中。当带有会话标识的HTTP请求到达Web服务器时,单个应用服务器需要在处理HTTP请求的过程中找到对应的会话数据(Session)。问题是会话数据需要保存在一台机器上。面对一个应用服务器集群,如果我第一次访问网站时,请求通过负载均衡器落到服务器A,那么我的Session就会创建在服务器A上,如果我们不处理,就不能保证以下请求每次都落在服务器A上。应用服务器集群1.SessionSticky使负载均衡器能够根据每个请求的会话标识进行请求转发。从会话到特定Web服务器的映射需要保存在负载均衡服务器上。SessionSticky方法很简单,但是有几个问题:1)。如果Web服务器宕机或重新启动,则这台机器上的会话数据将丢失。如果会话中有登录状态信息,那么用户将不得不重新登录。2).会话标识符是应用程序的信息。如果负载均衡服务器要将同一个会话的请求保存到一个Web服务器上,就需要分析应用层(OSI模型的第7层)。这个开销比第4层(传输层)交换大。3).负载均衡器已成为有状态节点。保存session到web服务器的映射,内存消耗比无状态节点大,容灾也会比较麻烦。2.SessionReplicationWeb服务器之间增加了session数据的同步,应用服务器集群中的每台服务器都有一份session数据。但是,SessionReplication也带来了一些问题:1)。同步Session数据会导致网络带宽开销。只要session数据有变化,就需要同步。机器越多,同步带来的网络带宽开销就越大。2)每个web服务器保存所有session数据。当多人同时访问网站时,每台机器保存session数据的内容会很严重。3.Session数据存放在不同的服务器,从同一个地方获取Session。session请求经过负载均衡服务器后,不会固定在同一个web服务器上,而是放在一个集中存储的地方。Web服务器在使用Session数据时,也是从这个Session数据的集中存储中读取的。会话数据集中存储的方案解决了第一种方案的内存问题,第二种方案占用网络带宽的情况较好。但是,仍然存在一些问题:1)。读写Session数据引入网络操作。与本地数据读取相比,问题在于延迟和不稳定。2).如果集中存储Session的机器或者集群出现问题,就会影响到我们的应用。4.CookieBased将Session数据放在Cookie中,在Web服务器上从Cookie中生成对应的Session数据。CookieBased方案不依赖于外部存储系统,因此从外部系统获取和写入数据不存在网络延迟和不稳定性。但是,仍然存在不足:1)。cookie的长度是有限的。Cookie的长度会限制Session数据的长度。2)..安全。会话数据是服务器端数据。该解决方案允许将服务器端数据发送到外部网络和服务器。3)..带宽消耗。数据中心的整体外部带宽消耗。4)..性能影响。每个HTTP请求和响应都携带Session数据。总结这四种方案都是可用的方案,但是对于大型网站来说,SessionSticky和Session数据集中存储是比较好的方案,而且这两种方案各有优势,需要在具体场景中进行选择和权衡。
