一、由来1、什么是session?服务器为每个用户创建一个会话,并存储与用户相关的信息,以便多个请求可以定位到相同的上下文。在web开发中,web-server可以为同一浏览器的访问用户自动创建session,并提供数据存储功能。最常见的是,用户的登录信息和用户信息将存储在会话中以保持登录状态。2.会话一致性问题是什么?只要用户不重启浏览器,每次发起HTTP短连接请求,服务器理论上都可以定位到session并保持session。当只有一台web-server提供服务时,每个HTTP短连接请求都能正确路由到对应的存储session的web-server(废话,因为只有一台)。此时,Web服务器无法保证高可用性。当使用具有“冗余+故障转移”的多个Web服务器来确保高可用性时,每个HTTP短连接请求可能不会被路由到正确的会话。如上图,假设用户的session包括登录信息记录在第一个web-server上,如果反向代理将请求路由到另一个web-server,可能找不到相关信息,用户需要重新登录。当web-server高可用时,如何保证session路由的一致性是今天要讨论的问题。2.session同步方式的思路:多个web-server相互同步session,让每个web-server包含所有的session优点:web-server支持的功能,应用不需要修改代码不足:session同步需要传输数据,占用内网带宽,有时间延迟。所有网络服务器都包含所有会话数据。数据量受内存限制,无法横向扩展。当有更多的网络服务器时,它会休息一下。3.客户端存储方式思路:service端存储所有用户的session,占用内存大。可以将session保存在浏览器cookie中,每一端只需要保存一个用户的数据即可。优点:服务器不需要存储。外网带宽数据存储在客户端,通过网络传输,存在泄露、篡改、窃取等安全风险。会话存储数据的大小受cookie限制。“端存”的方案虽然不常用,但确实是一种思路。3.反向代理哈希一致性的思想:为了保证高可用,web-server有多个冗余服务器。反向代理层可以做些什么来确保同一用户的请求落在一台网络服务器上吗?方案一:四层代理hash反向代理层使用用户ip做hash,保证同一个ip的请求落在同一个web-server上方案二:七层代理hash反向代理使用一个http协议中的某些协议使用一些业务属性进行hash,如sid、city_id、user_id等,可以更灵活的实现hash策略,保证同一个浏览器用户的请求落在同一个web-server上.优点:只需要改变nginx配置,不需要修改应用代码的负载均衡。只要hash属性统一,多个web-server的负载均衡,可以支持web-server的横向扩展(session同步方式不行,受内存限制)。不足:如果web-server重启,部分session会丢失,对业务造成影响。比如有的用户重新登录。如果web-server水平扩展并且会话在rehash后重新分配,一些用户将不会被路由到正确的会话。session一般都有有效期,所有的缺点有两点,可以认为相当于部分sessionfailure,一般问题不大。关于四层哈希还是七层哈希,我个人比较推荐前者:让专业的软件做专业的事,反向代理负责转发。除非万不得已,否则尽量不要引入应用层业务属性(比如有时多个机房,多个Live需要根据业务属性路由到不同机房的web-server)。4.后端统一存储思路:将session存储在web-server后端的存储层,数据库或缓存优点:水平扩展无安全隐患,数据库/缓存水平切分无需重启或扩容web-server不足sessionloss:增加了一个网络调用,需要修改应用代码,用于dbstorage或cache。个人推荐后者:session读取的频率会高,对数据库的压力会比较大。如果对session有高可用需求,可以使用缓存来实现高可用,但是大多数情况下session是可以丢失的,一般不需要考虑高可用。5.总结保证session一致性的常用架构设计方法:session同步方式:多个web-server相互同步数据client存储方式:一个用户只存储自己的数据反向代理hash一致性:四层hash和七层hash层Hash可以保证用户的请求落在一个web-server上,统一后端存储:web-server重启扩容,session不会丢失。对于方案3和方案4,我个人推荐后者:web层1。服务层的无状态是大型分布式系统的设计原则之一。会话属于状态。不应该放在web层让专业的软件做专业的事。Web服务器存储会话?或者让缓存做这样的事情!【本文为专栏作者《58神剑》原创稿件,转载请联系原作者】点此阅读更多该作者好文
