您当前的位置: 首页 >  分布式

淘东电商项目(30) -解决分布式Session共享问题

杨林伟 发布时间:2020-03-13 09:43:16 ,浏览量:3

引言

本文代码已提交至Github(版本号:3b2359205b2d49f9eae313d8cca119082dd7bc99),有兴趣的同学可以下载来看看:https://github.com/ylw-github/taodong-shop

本文主要解决分布式Session的问题。

本文目录结构: l____引言 l____ 1. 分布式Session的问题 l____ 2. 解决方案 l____ 3. spring-session l____ 4. 测试 l____总结

1. 分布式Session的问题

1.首先在「淘东电商」项目里复制一个portal-web,并修改端口号为8081,模拟门户集群,如下图: 在这里插入图片描述 2.项目新增controller,作为验证:

@RestController
public class TestSessionController {

    @Value("${server.port}")
    private Integer projectPort;// 项目端口

    @RequestMapping("/createSession")
    public String createSession(HttpSession session, String name) {
        session.setAttribute("name", name);
        return "当前项目端口:" + projectPort + " 当前sessionId :" + session.getId() + "在Session中存入成功!";
    }

    @RequestMapping("/getSession")
    public String getSession(HttpSession session) {
        return "当前项目端口:" + projectPort + " 当前sessionId :" + session.getId() + " 获取的姓名:" + session.getAttribute("name");
    }
}

3.Nginx负载均衡配置:


#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;


    keepalive_timeout  65;
  
    upstream  backServer{
	    server 192.168.18.166:8080;
	    server 192.168.18.166:8081;
	}
    server {
        listen       8099;
        server_name  192.168.166.137;
        location / {
           proxy_pass http://backServer;
           index  index.html index.htm;
        }      
    }
}

4.浏览器请求获取session,浏览器请求http://192.168.162.137:8099/getSession:

请求一次请求二次在这里插入图片描述在这里插入图片描述

可以看到两次Session的id不一致,并不是我们想要的。那该如何解决呢?下面来讲解决方案。

2. 解决方案

解决方案有如下几种:

  • 使用cookie来完成(缺点:不安全,操作不可靠)
  • 使用Nginx中的ip绑定策略,同一个ip只能在指定的同一个机器访问(缺点:不支持负载均衡)
  • 利用数据库同步session(缺点:效率不高)
  • 使用tomcat内置的session同步(缺点:同步可能会产生延迟)
  • 使用token代替session(已经有很好的解决方案了,使用spring-session)
  • 我们使用spring-session以及集成好的解决方案,存放在redis中(推荐)。
3. spring-session

step1:首先引入spring-session的maven依赖:



	org.springframework.session
	spring-session-data-redis


	org.apache.commons
	commons-pool2


	redis.clients
	jedis

step2:配饰Redis:

spring:
  redis:
    host: 192.168.162.136
    port: 6379
    jedis:
      pool:
        max-idle: 100
        min-idle: 1
        max-active: 1000
        max-wait: -1

step3: 启动类声明允许使用Session共享:

//maxInactiveIntervalInSeconds为SpringSession的过期时间(单位:秒)
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class AppPortalWeb {

    public static void main(String[] args) {
        SpringApplication.run(AppPortalWeb.class, args);
    }
}
4. 测试

启动项目: 在这里插入图片描述 首先浏览器创建session并设置内容到session:http://192.168.162.137:8099/createSession?name=‘ylw’ 在这里插入图片描述

浏览器请求:http://192.168.162.137:8099/getSession,可以看到两次的sessionid均为:f8b9a9ab-d285-4b04-8d98-66715cbdc132

请求8080请求8081在这里插入图片描述在这里插入图片描述

打开Medis,可以看到redis已经保存了相关的redis的值: 在这里插入图片描述

总结

本文主要讲解分布式环境下,使用spring-session解决session共享的问题。

关注
打赏
1688896170
查看更多评论

杨林伟

暂无认证

  • 3浏览

    0关注

    3183博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.3347s