分布式环境下Session共享问题

资料参考来源拉钩Java高薪训练营


前言

由于HTTP协议是无状态的,客户端和服务器的会话产生的数据不会被保留,所以第二次请求时服务器就无法识别你之前访问过,因为早期都是静态页面,可以无状态,后来动态内容多起来,就需要有状态来区分客户端的访问,然后就出现了Cookie和Session。

分布式环境下,客户端两次请求可能是两个服务器处理,那么这两个服务器就需要使用到相同的Session才能区分客户端的状态。

一、nginx的ip_hash策略

同一个客户端ip不变的情况下,通过hash算法会路由到同一台服务器,这样就直接避免了不同服务器Session不一致的问题。

优点:

  • 配置简单,不入侵代码。

缺点:

  • 服务器重启导致Session丢失
  • 可能单点负载高
  • 单点故障影响

二、Tomcat Session复制(不推荐)

多个Tomcat通过修改server.xml配置文件,达到集群Tomcat之前复制同步Session。

优点:

  • 不入侵代码
  • 方便服务器扩容和缩容
  • 适应各种负载均衡策略
  • 单个服务器重启或宕机不会造成Seesion丢失

缺点:

  • 性能较低
  • 浪费内存
  • 同步Seesion时有延迟性
  • 数据越多性能越差

三、Session共享(推荐)

1.简介

Session其实就是缓存,既然是缓存功能,那么我们可以把它交给专业的缓存中间件来管理,比如Redis。

当请求到达Tomcat时,通过过滤器去Redis获取Seesion,获取不到时生成一个并缓存到Redis。

优点:

  • 能适应各种负载均衡策略
  • 服务器重启或宕机不会造成Session丢失
  • 服务器扩容和缩容不会造成影响
  • 性能非常好,适合大集群

缺点:

  • 侵入代码,多了对Redis交互的代码

2.Spring Session

Spring Session使用起来非常的简单,首先添加pom依赖:

<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>

然后再application.properties配置文件中添加redis服务器连接信息:

spring.redis.host=ip
spring.redis.port=6379
spring.redis.connectionTimeout=5000
spring.redis.password=
spring.redis.database=0

就这样就实现了Session共享功能。其实实现原理主要是通过过滤器对请求进行过滤,请求被拦截到时,先从redis去拿session,没拿到时会生成一个session并缓存到redis中。

下面是一个简单的使用Spring Session做的登录拦截功能代码:
Controller:
在这里插入图片描述
Service:
在这里插入图片描述
LoginInterceptor拦截器:
在这里插入图片描述
注册拦截器:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值