Session是用户使用网站服务过程中一个十分重要的数据对象,它是客户端与服务器进行交互的基础数据,如果在交互过程中出现错误,可能会导致十分严重的后果,所以会话管理在大型分布式网站中是十分重要的一个模块。
那么如何才能实现高可用的会话管理呢?
Session Replication(会话复制)
如果是整个应用单台服务器的话,会话复制貌似用处不是很大,因为单台服务器挂了,会话再留着也没什么卵用了,但是多台服务器的话,就因为其中一台服务器宕机,导致用户需要重新连接会话,那这个体验就大大减分了。
这时候会话复制就派上了大用场,当一个客户端连接到一台服务器的时候,这时候会话数据同时也产生了,为了避免上述出现的场景,那么在没有宕机前,就做一下会话复制的工作,即将此会话数据复制到每一台服务器上,每一台服务器都存留一份副本,这时候如果其中一台宕机了,可以切换到另外一台服务器继续工作,实现了高可用的目的。
但是会话复制也有它的缺陷,就是当用户使用高峰期的时候,服务器之间需要复制大量的session数据,这时候服务器就有些吃不消,甚至会出现内存不够的情况。
Session Tricky(会话粘滞)
会话粘滞的思想跟源地址哈希法有点类似,它的思想就是客户端发过来的请求都发送到一台服务器上,比如利用Session对象的HashCode,然后根据HashCode再去决定要把这个会话放在哪台服务器上,这一步可以用serverPosition=hashCode%serverSize
来解决。这样具有相同serverPosition
的会话就全部放在一台服务器上。
但这种方法也有一个致命的问题,那就是如果一台服务器挂了,那这台服务器上的会话集合就全挂了,用这种方法去实现高可用,那风险还是大大滴。
利用Cookie保存Session
以上两种方法出现的Session丢失,说到底是因为Session只保存在了内存中,内存一出错,大家一起玩儿完。我们可以这么考虑,如果Session能够像其他数据一样能够持久化到硬盘上,那这个问题不就解决了么,这样做无非就是读取速度没直接从内存中找那么爽罢了。
有了这个想法以后,我们可以想到Cookie不就是这样的想法么,这玩意儿不就保留了一些网站的缓存数据么,那好,既然有现成的车,那我们就搭一趟了,我们可以把Session数据临时保存在Cookie中,如果出现宕机,下次再读取的时候,依然还是存在的。
但是这种方法也有它的缺点,基本也就是Cookie本身的缺点:Cookie本身大小受限制,Cookie的安全性一直也是个老话题,还有就是带宽消耗和性能影响。
终极利器——Session服务器
上面几种方法无论是谁,要是真想达到高可用,貌似还是差那么点,那么单独搞一个Session服务器,以上这些问题就迎刃而解了。
首先、Session服务器与其他服务器隔离,所有与Session相关的操作(复制,粘滞)只在Session服务器上折腾,不会影响其他服务器的资源使用。
第二、Session服务器可以做分布式会话缓存(如memcache,ActiveMQ),如果需要持久化可以利用类似Redis这样的产品,使其符合Session的使用要求。