存在的一致性问题
客户端发送一个请求,经过负载均衡后该请求会被分配到服务器中的其中一个,由于不同服务器含有不同的web服务器(例如Tomcat),不同的web服务器中并不能发现之前web服务器保存的session信息,就会再次生成一个sessionID,之前的状态就会丢失。
解决方案
-
客户端存储。直接将信息存储在cookie中。
缺点:
数据存储在客户端,存在安全隐患
cookie存储大小、类型存在限制
数据存储在cookie中,如果一次请求cookie过大,会给网络增加更大的开销 -
session复制。小型企业应用使用较多的一种服务器集群session管理机制。
缺点:
session同步的原理是在同一个局域网里面通过发送广播来异步同步session的,一旦服务器多了,并发上来了,session需要同步的数据量就大了,需要将其他服务器上的session全部同步到本服务器上,会带来一定的网路开销,在用户量特别大的时候,会出现内存不足的情况。
优点:
Tomcat内部已经支持分布式架构开发管理机制,可以对tomcat修改配置来支持session复制,在集群中的几台服务器之间同步session对象,使每台服务器上都保存了所有用户的session信息,这样任何一台本机宕机都不会导致session数据的丢失,而服务器使用session时,也只需要在本机获取即可。 -
session绑定。我们利用nginx的反向代理和负载均衡,之前是客户端会被分配到其中一台服务器进行处理,具体分配到哪台服务器进行处理还得看服务器的负载均衡算法(轮询、随机、ip-hash、权重等),但是我们可以基于nginx的ip-hash策略,可以对客户端和服务器进行绑定,同一个客户端就只能访问该服务器,无论客户端发送多少次请求都被同一个服务器处理。
缺点:
容易造成单点故障,如果有一台服务器宕机,那么该台服务器上的session信息将会丢失
前端不能有负载均衡,如果有,session绑定将会出问题 -
基于redis存储session。
优点:
数据保存在redis中,无缝接入,不存在任何安全隐患。
redis自身可做集群,搭建主从,同时方便管理。
spring为我们封装好了spring-session,直接引入依赖即可。
spring-session-data-redis
spring-boot-data-starter-redis
缺点:
多了一次网络调用,web容器需要向redis访问。
【参考文档】
4种分布式session解决方案