分布式架构下,session共享有什么方案么?
Posted shoshana-kong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式架构下,session共享有什么方案么?相关的知识,希望对你有一定的参考价值。
分布式架构下的session共享,也可以称作分布式session一致性;关于这个问题,和大家说一说解决方案(如果有其他的方案,可以留言讨论)。
session的作用
如果大家做过web应用开发的话,应该对session比较熟悉;服务器会为每个用户创建一个会话,存储用户的相关信息,以便在后面的请求中,可以够定位到同一个上下文。
例如用户在登录之后,再进行页面跳转的时候,存储在session中的信息会一直保持,如果用户还没有session,那么服务器会创建一个session对象,直到会话过期或主动放弃后(退出),服务器才会把session终止掉。
分布式架构中的session问题
在N年前,那个都是单个服务器的年代,session直接保存在服务器中,是一点问题没有的,而且实现起来很容易。
但是随着分布式架构的流行,单个服务器已经不能满足系统的需要了,通常都会把系统部署在多台服务器上,通过负载均衡把请求分发到其中的一台服务器上,这样很可能同一个用户的请求被分发到不同的服务器上,因为session是保存在服务器上的,那么很有可能第一次请求访问的A服务器,创建了session,但是第二次访问到了B服务器,这时就会出现取不到session的情况。
于是,分布式架构中,session共享就成了一个很大的问题。
解决方案
- 不要有session:大家可能觉得我说了句废话,但是确实在某些场景下,是可以没有session的,其实在很多接口类系统当中,都提倡【API无状态服务】;也就是每一次的接口访问,都不依赖于session、不依赖于前一次的接口访问;
- 存入cookie中:将session存储到cookie中,但是缺点也很明显,例如每次请求都得带着session,数据存储在客户端本地,是有风险的;
- session同步:对个服务器之间同步session,这样可以保证每个服务器上都有全部的session信息,不过当服务器数量比较多的时候,同步是会有延迟甚至同步失败;
- 使用nginx(或其他复杂均衡软硬件)中的ip绑定策略,同一个ip只能在指定的同一个机器访问,但是这样做风险也比较大,而且也是去了负载均衡的意义;
- 我们现在的系统会把session放到Redis中存储,虽然架构上变得复杂,并且需要多访问一次Redis,但是这种方案带来的好处也是很大的:实现session共享,可以水平扩展(增加Redis服务器),服务器重启session不丢失(不过也要注意session在Redis中的刷新/失效机制),不仅可以跨服务器session共享,甚至可以跨平台(例如网页端和APP端)。
米寸阳光 科技公司工程师
什么是session?
服务器为每个用户创建一个会话,存储用户的相关信息,以便多次请求能够定位到同一个上下文。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。
当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。
Web开发中,web-server可以自动为同一个浏览器的访问用户自动创建session,提供数据存储功能。最常见的,会把用户的登录信息、用户信息存储在session中,以保持登录状态。
什么是session一致性问题?
只要用户不重启浏览器,每次http短连接请求,理论上服务端都能定位到session,保持会话。
分布式session:
单服务器web应用中,session信息只需存在该服务器中,这是我们前几年最常接触的方式,但是近几年随着分布式系统的流行,单系统已经不能满足日益增长的百万级用户的需求,集群方式部署服务器已在很多公司运用起来,当高并发量的请求到达服务端的时候通过负载均衡的方式分发到集群中的某个服务器,这样就有可能导致同一个用户的多次请求被分发到集群的不同服务器上,就会出现取不到session数据的情况,于是session的共享就成了一个问题。
这个时候就需要解决Session一致性。
Session一致性解决方案:
分布式Session共享的4类技术方案,与优劣势比较
1、session复制
session复制是早期的企业级的使用比较多的一种服务器集群session管理机制。
应用服务器开启web容器的session复制功能,在集群中的几台服务器之间同步session对象,使得每台服务器上都保存所有的session信息,这样任何一台宕机都不会导致session的数据丢失,服务器使用session时,直接从本地获取。
简介:将一台机器上的Session数据广播复制到集群中其余机器上
session复制使用场景:机器较少,网络流量较小
优点:实现简单、配置较少、当网络中有机器Down掉时不影响用户访问
缺点:广播式复制到其余机器有一定廷时,带来一定网络开销。
这种方式在应用集群达到数千台的时候,就会出现瓶颈,每台都需要备份session,出现内存不够用的情况。
2、session绑定
利用hash算法,比如nginx的ip_hash,使得同一个Ip的请求分发到同一台服务器上。
session绑定使用场景:机器数适中、对稳定性要求不是非常苛刻
优点:实现简单、配置方便、没有额外网络开销
缺点:网络中有机器Down掉时、用户Session会丢失、容易造成单点故障。
这种方式不符合对系统的高可用要求,因为一旦某台服务器宕机,那么该机器上的session也就不复存在了,用户请求切换到其他机器后么有session,无法完成业务处理。
3、利用cookie记录session
session记录在客户端,每次请求服务器的时候,将session放在请求中发送给服务器,服务器处理完请求后再将修改后的session响应给客户端,这里的客户端就是cookie。
缺点
比如受cookie大小的限制,能记录的信息有限;
每次请求响应都需要传递cookie,影响性能,如果用户关闭cookie,访问就不正常。
优点:
cookie的简单易用,可用性高,支持应用服务器的线性伸缩,而大部分要记录的session信息比较小,因此事实上,许多网站或多或少的在使用cookie记录session。
4、session服务器
session服务器可以解决上面的所有的问题,利用独立部署的session服务器(集群)统一管理session,服务器每次读写session时,都访问session服务器。
这种解决方案事实上是应用服务器的状态分离,分为无状态的应用服务器和有状态的session服务器,然后针对这两种服务器的不同特性分别设计架构。
对于有状态的session服务器,一种比较简单的方法是利用分布式缓存(redis、memcached), 或者存储在数据库(如mysql)等。在这些产品的基础上进行包装,使其符合session的存储和访问要求。
如果业务场景对session管理有比较高的要求,比如利用session服务基层单点登录(sso),用户服务器等功能,需要开发专门的session服务管理平台。
session服务器使用场景:集群中机器数多、网络环境复杂。
优点:可靠性好
缺点:实现复杂、稳定性依赖于缓存的稳定性、Session信息放入缓存时要有合理的策略写入。
以上是关于分布式架构下,session共享有什么方案么?的主要内容,如果未能解决你的问题,请参考以下文章
分布式环境下5种session处理策略(大型网站技术架构:核心原理与案例分析 里面的方案)