唐僧喜欢小龙女

导航

分布式session的解决方案

1、采用分布式部署后会产生什么Session问题

如果通过Nginx的方式配置了负载均衡(轮询的方式)页面请求到不同后端服务器后都会产生创建新的Session,导致两个不服务器有不同的Session。

2、分布式session问题产生的原因

 

Session的底层是基于Cookie的,我们每次服务端创建了一个Session 都会向Cookie里面写入一个key是JSESSONID,value
是SessionId 的键值对。当我们关闭浏览器的时候Cookie 就消失了。在打开页面请求后端服务时请求里面没有Cookie信息。如果通过Nginx的方式配置了负载均衡(轮询的方式),
请求到两个服务端后,内存中根据SessionId找不到原来创建的Session,所以就新创建一个Session。这就是分布式Session产生的原因。


3、分布式session问题的解决办法

3.1 使用 Redis

使用docker Redis 服务端

2、创建存放redis文件夹用于存放redis
mkdir /Users/gaoheqiang/redis-data3、使用redis镜像运行redis容器
docker run -p 6379:6379 -v /usr/data/redis/data:/data --restart=always --name redis -d redis:latest redis-server --appendonly yes --requirepass "lcl123456"
  命令说明:
  -p:宿主机端口与容器端口映射
  -v:挂载,将容器中的redis持久化数据挂载到宿主机,避免容器重启导致的数据丢失。
  --restart=always:无论什么情况挂壁,总是重启
  --name:容器名称
  -d:使用指定的镜像(redis的4.0.8版本的镜像)在后台运行容器
  --appendonly yes:redis运行时开启持久化 
  --requirepass "lcl123456":设置redis登陆密码

创建session 的配置文件

@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class SessionConfig {
    @Value("${redis.hostname}")
    String hostName;

    @Value("${redis.port}")
    int port;
    @Value("${spring.redis.password}")
    String password;
    @Bean
    public JedisConnectionFactory jedisConnectionFactory(){
        JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
        connectionFactory.setPort(port);
        connectionFactory.setHostName(hostName);
        connectionFactory.setPassword(password);
        return connectionFactory;
    }

    @Bean
    public StringRedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        return new StringRedisTemplate(redisConnectionFactory);
    }

}

初始化Session 配置

/**
 * 初始化Session配置
 */
public class SessionInitializer extends AbstractHttpSessionApplicationInitializer {

    public SessionInitializer() {
        super(SessionInitializer.class);
    }
}

Spring-Sesion实现的原理

当Web服务器接收到请求后,请求会进入对应的Filter进行过滤,将原本需要由Web服务器创建会话的过程转交给Spring-Session进行创建。
Spring-Session会将原本应该保存在Web服务器内存的Session存放到Redis中。然后Web服务器之间通过连接Redis来共享数据,达到Sesson共享的目的。

验证结果

通过nginx 访问后端的服务,第一次是访问时Session 是 新建的,第二次是用原来的,这样验证使用Redis 解决了分布式session的问题。

 

posted on 2022-02-22 14:22  与时具进&不忘初心  阅读(134)  评论(0编辑  收藏  举报