Session一致性的四种解决方案

1. Session的定义

前面的文章中介绍过session,和cookie一样也是一种会话技术,但是是存在服务端的,主要作用就是通过服务端记录用户的状态。推荐阅读:万字详解认证授权

2. session一致性问题

只要用户不重启浏览器,每次http短连接请求,理论上服务端都能定位到session,保持会话。

但是只有一台web服务器提供服务时,是无法保证服务的高可用的。为了保证高可用,有多台web服务器时,每次http短连接请求就不一定能路由到正确的session了。

3. 解决方案

3.1 session同步法

多个web服务器之间相互同步session,这样每个web服务器之间都包含全部的的session。

优点:web服务器支持的功能,应用程序不需要修改代码。

缺点:

  • session的同步需要数据传输,占内网带宽,有时延
  • 所有web服务器都包含所有session数据,数据量受内存限制,无法水平扩展

3.2 客户端存储法

服务端存储所有用户的session,内存占用较大,可以将session存储到浏览器cookie中,每个客户端只要存储一个用户的数据了。

优点:服务端不需要存储。

缺点:

  • 每次http请求都携带session,占外网带宽
  • 数据存储在客户端上,并在网络传输,存在泄漏、篡改、窃取等安全隐患
  • session存储的数据大小受cookie限制

这种方式不常用。

3.3 反向代理hash一致性

多个web服务器为了保证高可用,有多台冗余,反向代理层可以通过一些手段,让同一个用户的请求保证落在一台web服务器上。

3.3.1 四层代理hash

反向代理层使用用户ip来做hash,以保证同一个ip的请求落在同一个web服务器上。

3.3.2 七层代理hash

反向代理使用http协议中的某些业务属性来做hash,例如sid,city_id,user_id等,能够更加灵活的实施hash策略,以保证同一个浏览器用户的请求落在同一个web服务器上。

优点:

  • 只需要改nginx配置,不需要修改应用代码
  • 负载均衡,只要hash属性是均匀的,多台web服务器的负载是均衡的
  • 可以支持web服务器水平扩展

缺点:

  • 如果web服务器重启,一部分session会丢失,产生业务影响,例如部分用户重新登录
  • 如果web服务器水平扩展,rehash后session重新分布,也会有一部分用户路由不到正确的session

session一般是有有效期的,所以不足中的两点,可以认为等同于部分session失效,一般问题不大。

对于四层hash还是七层hash,个人推荐前者:让专业的软件做专业的事情,反向代理就负责转发,尽量不要引入应用层业务属性。

3.4 后端统一存储

将session存储在web-server后端的存储层,数据库或者缓存。

优点:

  • 没有安全隐患
  • 可以水平扩展,数据库/缓存水平切分即可
  • web服务器重启或者扩容都不会有session丢失

缺点:增加了一次网络调用,并且需要修改应用代码。

对于db存储还是cache,个人推荐后者:session读取的频率会很高,数据库压力会比较大。如果有session高可用需求,cache可以做高可用,但大部分情况下session可以丢失,一般也不需要考虑高可用。

4. 总结

保证session一致性的常见方法:

  • session同步法:多台web-server相互同步数据
  • 客户端存储法:一个用户只存储自己的数据
  • 反向代理hash一致性:四层hash和七层hash都可以做,保证一个用户的请求落在一台web-server上
  • 后端统一存储:web-server重启和扩容,session也不会丢失

对于方案3和方案4,个人建议推荐后者:

  • web层、service层无状态是大规模分布式系统设计原则之一,session属于状态,不宜放在web层
  • 让专业的软件做专业的事情,让cache去存session

你可能感兴趣的:(java,java,分布式)