前言
服务器集群情况下通常要考虑分布式session一致性问题,以下提供了四种解决方案。
Session复制
如果此时 Tomcat1 Session 存在用户信息,而 Tomcat2 上没有存在。这时如果我们将 Tomcat1 的 Session 复制到 Tomcat2 上,后面 Nginx 将请求转发到 Tomcat2 上,由于 Tomcat2 存在 Session ,这时就不需要再重新登录了。
优点:
只需要修改 Tomcat 配置就好,我们应用代码都不用修改了。
缺点:
- 第一,Session 复制传输需要占用内网带宽。
- 第二,我们的例子就只有两台机器,这个复制性能还可以。但是假设我们有 N 台机器,那么每次复制都要复制给 N-1 台机器,如果机器很多,可能会形成网络风暴,复制性能也会呈指数级下降。
- 第三, Tomcat 需要保存所有的 Session 数据,这个方案的 Session 存储在内存中,容易受到机器的总内存的限制。我们没办法通过加机器的方式水平扩展,我们能做的方式就是加大机器内存。但是机器内存越大,价格真的很贵!!!
Session 前端存储
不存 Tomcat Session 里,把信息存到浏览器的 Cookie 中。每个用户浏览器存储自己的 Cookie 信息,服务端不需要存储,这就解决了 Session 复制方案的缺陷。
用户每次请求发送Cookie,判断 Cookie 里用户信息。
优点:代价小,实现简单
缺点:
- 不安全,需要额外加密
- 消耗外围带宽
- 储存大小受限制
Session 粘滞
修改 Nginx 默认的负载均衡策略,使用 IP Hash 的方式。
Nginx 会使用请求者的 IP 来做 Hash,然后分发到一台机器上,这样可以保证同一 IP 的请求都落在同一台 Tomcat 上。
优点:
- 只要请求来源 IP 足够的随机,那么 IP HASH 之后两台应用上的流量将会足够随机。
- 方便水平扩展,只要修改 Nginx 配置即可。
缺点:
- 公司内网IP出口通常固定,容易变成单点
- Tomcat重启,session丢失,相关用户重新登录
后端集中储存
使用中间件session保存session信息,每次去请求redis。
优点:
Web 应用重启或扩容,Session 也无需丢失,当然前提是 Redis 不能宕机
缺点:
每次请求redis,增加网络开销。