分布式Session一致性?
说白了就是服务器集群Session共享的问题
Session的作用?
Session 是客户端与服务器通讯会话跟踪技术,服务器与客户端保持整个通讯的会话基本信息。
客户端在第一次访问服务端的时候,服务端会响应一个sessionId并且将它存入到本地cookie中,在之后的访问会将cookie中的sessionId放入到请求头中去访问服务器,如果通过这个sessionid没有找到对应的数据那么服务器会创建一个新的sessionid并且响应给客户端。
分布式Session存在的问题?
假设第一次访问服务A生成一个sessionid并且存入cookie中,第二次却访问服务B客户端会在cookie中读取sessionid加入到请求头中,如果在服务B通过sessionid没有找到对应的数据那么它创建一个新的并且将sessionid返回给客户端,这样并不能共享我们的Session无法达到我们想要的目的。
解决方案:
1)使用cookie来完成(很明显这种不安全的操作并不可靠)
2)使用Nginx中的ip绑定策略,同一个ip只能在指定的同一个机器访问(不支持负载均衡)
3)利用数据库同步session(效率不高)
4)使用tomcat内置的session同步(同步可能会产生延迟)
5)使用token代替session
6)我们使用spring-session以及集成好的解决方案,存放在redis中
解决方案
1.session复制
应用服务器开启web容器的session复制功能,在集群中的几台服务器之间同步session对象,
多个web-server之间相互同步session,这样每个web-server之间都包含全部的session。
实现方式:
① 设置tomcat ,server.xml 开启tomcat集群功能
Address:填写本机ip即可,设置端口号,预防端口冲突。
② 在应用里增加信息:通知应用当前处于集群环境中,支持分布式 在web.xml中添加选项。
不足:
1)、session的同步需要数据传输,占内网带宽,有时延
2)、有更多web-server时,容易造成网络风暴
2. 客户端存储
将session存储到浏览器cookie中。每次请求服务器的时候,将session放在请求中发送给服务器,服务器处理完请求后再将修改后的session响应给客户端。
缺点:
1)、数据存储在端上,并在网络传输,存在泄漏、篡改、窃取等安全隐患
2)、session存储的数据大小受cookie限制
3. 反向代理hash一致性
反向代理层使用用户ip来做hash,以保证同一个ip的请求落在同一个web-server上。
实现方式:以Nginx为例,在upstream模块配置ip_hash属性即可实现粘性Session。
upstream mycluster{
#这里添加的是上面启动好的两台Tomcat服务器
ip_hash;#粘性Session
server 192.168.22.229:8080 weight=1;
server 192.168.22.230:8080 weight=1;
}
不足:
1)、如果web-server重启,一部分session会丢失,产生业务影响,例如部分用户重新登录。
2)、如果web-server水平扩展,rehash后session重新分布,也会有一部分用户路由不到正确的session
4. 后端统一集中存储
将session存储在web-server后端的存储层,数据库或者缓存,一般用redis/memchache缓存。