Springboot Session共享

作者: HeloWxl | 来源:发表于2021-05-21 10:29 被阅读0次

    本文参考 Spring Boot 一个依赖搞定 session 共享,没有比这更简单的方案了!

    在传统的单服务架构中,只有一个服务器,那就不会存在session共享的问题,但如果在分布式/集群项目中,session共享则是一个必须面对的问题。

    image.png

    这样就会出现一个问题,比如说,当客户端发起了一个请求,这个请求到达Nginx之后,被转发到了服务器A,然后在服务器A上往session保存了一份数据,下次又来一个请求,这个请求被转发到 Tomcat B 上,此时再去 Session 中获取数据,发现没有之前的数据。对于这一类问题的解决,思路很简单,就是将各个服务之间需要共享的数据,保存到一个公共的地方(主流方案就是 Redis):

    image.png
    • 当所有 Tomcat 需要往 Session 中写数据时,都往 Redis 中写,当所有 Tomcat 需要读数据时,都从 Redis 中读。这样,不同的服务就可以使用相同的 Session 数据了。

    • 这样的方案,可以由开发者手动实现,即手动往 Redis 中存储数据,手动从 Redis 中读取数据,相当于使用一些 Redis 客户端工具来实现这样的功能,毫无疑问,手动实现工作量还是蛮大的。

    • 一个简化的方案就是使用 Spring Session 来实现这一功能,Spring Session 就是使用 Spring 中的代理过滤器,将所有的 Session 操作拦截下来,自动的将数据 同步到 Redis 中,或者自动的从 Redis 中读取数据。

    • 对于开发者来说,所有关于 Session 同步的操作都是透明的,开发者使用 Spring Session,一旦配置完成后,具体的用法就像使用一个普通的 Session 一样。

    演示

    创建一个springboot项目

    image.png

    依赖

           <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!--用于连接redis-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
            <!--用于使用redis接管session-->
            <dependency>
                <groupId>org.springframework.session</groupId>
                <artifactId>spring-session-data-redis</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <!--工具类,非必需-->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>4.1.0</version>
            </dependency>
    

    application.yml

    server:
      port: 8088
    spring:
      redis:
        host: localhost
        port: 6379
    

    IndexController

    @RestController
    @RequestMapping(value = "/")
    public class IndexController {
    
        @Value("${server.port}")
        private String port;
        private String username = "wangxianlin";
        private String password = "123456";
        private String nickname = "Halo";
    
    
        @RequestMapping(value = "/login")
        public Map<String, Object> getSession(HttpServletRequest request,@RequestParam("user") String user,@RequestParam("pwd") String pwd) {
            Map<String, Object> map = new HashMap<>();
            if (username.equals(user) && password.equals(pwd)){
                request.getSession().setAttribute("user", "当前登录用户是:"+nickname);
                map.put("msg", "登录成功");
                map.put("port",port);
            }else {
                map.put("msg", "账号或密码错误");
            }
            return map;
        }
    
        @RequestMapping(value = "/get")
        public Map<String, Object> get(HttpServletRequest request) {
            Map<String, Object> map = new HashMap<>();
            String user = (String) request.getSession().getAttribute("user");
            map.put("msg", StrUtil.isEmpty(user)?"用户未登录":user);
            map.put("port",port);
            return map;
        }
    }
    
    

    在启动类上加上注解
    @EnableRedisHttpSession

    将项目打成jar包

    image.png

    启动项目

    前提:redis 是否已经开启?

    将jar 分别以 8088和8089端口进行启动
    java -jar --server.port=8088
    java -jar --server.port=8089
    
    8088 8089

    配置nginx

     upstream web-server { 
            server localhost:8088;  
            server localhost:8089;
        }
    
        server {
            listen       9000;
            server_name  localhost;
            location / {
                proxy_pass http://web-server;
            }
      }
    

    启动nginx

    由于我这里有三个nginx配置文件,然后我想启动nginx-origanal.conf 咋办呢?


    image.png

    命令 人家早就给我们安排好了,我们只需要这样。

    image.png

    测试

    未登录状态下

    http://localhost:9000/get
    
    image.png image.png

    登录:

    http://localhost:9000/login?user=wangxianlin&pwd=123456
    
    image.png
    http://localhost:9000/get
    
    image.png image.png

    看一下redis里面

    image.png

    以上内容参考于: Spring Boot 一个依赖搞定 session 共享,没有比这更简单的方案了!

    相关文章

      网友评论

        本文标题:Springboot Session共享

        本文链接:https://www.haomeiwen.com/subject/eizijltx.html