1、Session共享问题解决
a、session复制,tomcat等webserver等支持
优点: 1、web-server(tomcat)原生支持,只需要修改配置文件
缺点: 1、session同步需要数据传输,占用大量网络带宽,降低了服务器群的业务处理能力
2、任意一台web-server保存的数据都是所有web-server的session总和,受到内存限制无法水平扩展更多的web-server
3、大型分布式集群情况下,由于所有web-server 都会保存数据,不可取
b、放在cookie里面让客户端存储
优点:1、服务器不需要存储session,节省服务器资源
缺点:1、每次http请求,携带用户在cookie中的完整信息,浪费带宽
2、session数据放在cookie中,cookie有长度限制4k,不能保存大量信息
3、session数据放在cookie中,存在泄露、篡改、窃取等安全隐患
c、hash一致性,在nginx做转发时,使用ip_hash,让同IP的请求分发到同一个服务下
优点:1、只需要修改nginx配置,不需要修改应用代码
2、负载均衡,只要hash属性的值分布时均匀的,多台web-server的负载就是均衡的
3、可以支持web-server水平扩展(session同步方案不可无限扩展,受内存限制)
缺点:1、session还是存在web-server中,所以web-server重启可能导致部分session丢失,影响业务,部分用户需重新登录
2、如果web-server水平扩展,rehash后session重新分布,也会又一部分用户路由不到正确的session
综述:此方案缺点问题不大,因为session本来就是有有效期的。
d、统一存储
优点:没有安全隐患,可以水平扩展、数据库/缓存水平切分即可,web-server重启、扩容都不会有session丢失
缺点:1、增加了一次网络调用,并且需要修改应用代码,如将所有的getSession方法替换为从Redis查数据的方式,redis获取数据比内存慢很多
2、上面的缺点可以用SpringSession完美解决
SpringSession 解决session共享问题
1、pom.xml中引入以下依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
2、application.properties 中加入配置
spring.redis.host=192.168.3.91
spring.redis.port=6379
spring.session.store-type=redis
3、新建一个Config类,加入以下内容
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("JZSESSIONID");
serializer.setDomainName("jz.com");
return serializer;
}
如果springboot启动时报以下错误,则检查是否有加入redis的依赖包
Consider defining a bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory' in your configuration.
高并发有三宝, 缓存(redis)、异步(CompletableFuture)、队排好(rabbitMQ)