资料参考来源拉钩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拦截器:
注册拦截器: