什么是session?nginx
因为HTTP协议是无状态的协议,所以它不会去记住上一次浏览器访问服务器时的信息。同一个用户的两次操做,与两个不一样用户的操做,对它来讲是同样的。 这样虽然知足了互联网web应用的海量访问的需求,可是对于现今相似电商的应用来讲,是须要实现登陆以及身份验证需求的,可是无状态的HTTP显然是作不到的,这样才出现了session。web
Web服务器为每一个用户建立一个会话,存储用户的相关信息,以便屡次请求可以定位到同一个上下文。数据库
web-server能够自动为每个浏览器访问的用户自动建立session,提供数据存储功能。最多见的,会把用户的登陆信息、用户信息存储在session中,以保持持续登陆状态。后端
什么是session一致性问题?浏览器
每次http短链接请求,理论上服务端都能定位到session,保持会话状态。缓存
当应用只有一台web-server提供服务时,每次浏览器发送http请求,都可以正确路由到存储session的对应web-server(由于只有一台)。安全
此时的web-server是没法保证高可用的,所以若是咱们采用Nginx反向代理,而后加上web-server “冗余+故障转移”的方案,用多台web-server来保证高可用时,每次http短链接请求就不必定能路由到正确的session了。服务器
好比第一次用户登陆的时候,Nginx路由到 web-server1,且在web-server1上建立了session,当第二次访问时,Nginx路由到了web-server2上。此时web-server2上是没有用户的登陆信息的,那么就会致使用户须要从新登陆,这样用户体验确定是很差的。cookie
那么如何保证分布式系统的session路由一致性呢?网络
1、session同步法
这个方案的思路就是,多个web-server之间相互同步session,这样每一个web-server之间都包含所有的session。
优势:应用程序不须要修改代码。
不足:
session的同步须要数据传输,占内网带宽,有时延
全部web-server都包含全部session数据,数据量受内存限制,没法水平扩展。
2、客户端存储法
这个方案的思路就是,服务端存储全部用户的session的话内存占用较大,能够将session存储到浏览器cookie中,每一个端只要存储一个用户的数据了。
优势:服务端不须要存储。
缺点:
每次http请求都携带session,占外网带宽
数据存储在端上,并在网络传输,存在泄漏、篡改、窃取等安全隐患
session存储的数据大小受cookie限制
“端存储”的方案虽然不经常使用,但确实是一种思路。
3、反向代理hash一致性
这个方案的思路就是,在反向代理层作点文章,让同一个用户的请求保证落在一台web-server上。
咱们能够在反向代理层使用用户ip来作hash,以保证同一个ip的请求落在同一个web-server上。
优势:
只须要改nginx配置,不须要修改应用代码
负载均衡,只要hash属性是均匀的,多台web-server的负载是均衡的
能够支持web-server水平扩展
不足:
若是web-server重启,一部分session会丢失,例如部分用户从新登陆
若是web-server水平扩展,rehash后session从新分布,也会有一部分用户路由不到正确的session
4、后端统一存储法
思路就是,将session存储在web-server后端的存储层,数据库或者缓存。
优势:
没有安全隐患
能够水平扩展,数据库/缓存水平切分便可
web-server重启或者扩容都不会有session丢失
不足:增长了一次网络调用,而且须要修改应用代码。
对于db存储仍是cache,我的推荐后者:session读取的频率会很高,数据库压力会比较大。若是有session高可用需求,cache能够作高可用,但大部分状况下session能够丢失,通常也不须要考虑高可用。
总结
保证session一致性的架构设计常见方法:
session同步法:多台web-server相互同步数据
客户端存储法:一个用户只存储本身的数据在cookie中。
反向代理hash一致性:保证一个用户的请求落在一台web-server上
后端统一存储:web-server重启和扩容,session也不会丢失
对于方案3和方案4,我的建议推荐后者:
web层、service层无状态是大规模分布式系统设计原则之一,session属于状态,不宜放在web层。