目录
1.什么是session
2.session共享问题
2.1.session复制同步
2.2.存在客户端
2.3.一致性hash
2.4.统一存储
1.什么是session
HTTP是无状态的,session是一种会话保持技术,目的就是以一种方式来记录http请求之间需要传递、交互的数据。
不是每次http请求都会产生的新的session,而是在服务端手动创建的,例如HttpServletRequest.getSession(true)。
session创建后会返回给客户端sessionID,sessionID会以cookie的形式携带在后续的请求中,直到浏览器关闭,一次会话结束。
详细的关于session以及其他会话保持技术的内容可参见博主的另一篇文章:
会话保持技术:cookie、session__BugMan的博客-CSDN博客
2.session共享问题
由于session是存储在单个的web server中,在分布式的环境下会存在全局不共享的问题,访问A服务器创建的session,后续请求负载均衡到B服务器上后肯定是无法找到该session的。
session共享有以下解决方案:
-
session复制同步
-
session存在客户端
-
一致性hash
-
统一存储
2.1.session复制同步
web server间以复制的方式进行session的同步,每个web server节点都有存放着全局的所有session。缺点是太浪费存储空间,复制的速度也很慢,不高效。
2.2.存在客户端
存在客户端会导致后续请求的数据包变大,浪费带宽,并且存在被篡改和破解的风险。
2.3.一致性hash
通过一致性hash算法将相同IP的请求负载均衡到同一个服务器,这样也能避免session不共享带来的问题。
关于一致性hash博主的另一篇文章有对其有详细论述:一致性hash算法__BugMan的博客-CSDN博客
缺点:
-
web server重启session会丢失
-
web server水平拓展后全局需要rehash,后续的一些请求会找不到正确的路由。
不过以上缺点都是能接受的代价,因此一致性hash是个解决分布式场景下session不共享问题的好办法。
2.4.统一存储
将本来想存在session里的数据存在第三方存储如Redis中。
缺点:
-
额外增加了一次网络调用
-
如果是已经写好了的老项目进行改造的话,还需要在编码里把所有session操作都改为对第三方存储的操作。
Spring也注意到了这个问题,提供了SpringSession框架,以上缺点使用SpringSession框架,都可以完美解决。