分布式环境下的session 共享-基于spring-session组件和Redis实现

1、问题概述

不是所有的项目都是单机模式的,当一个项目服务的局域比较广,用户体量比较大,数据量较大的时候,我们都会将项目部署到多台服务器上,这些个服务器都是分布在不同的区域,这样实现了项目的负载和并发量,但同时也引发了一些问题。如我们将登录信息放在session中,通过session中的用户信息判断用户是否登录的时候。如下图:

从下图可以看出,当用户第一次携带正确的用户名和密码到达服务器1的时候,用户信息会被存放在服务器1的内存中,当用户再次发起请求的时候,这个时候可能访问的是服务器2,这个时候服务器2无法获取存放在服务器1中的用户信息,从而引发报错,提示用户未登录。

这个时候我们会有很多的解决方案,本案例讲述使用spring-session+redis的解决方案。

Redis是基于内存的,数据的读写性能都非常的高。

如下图:

5.2、Linux中安装Redis过程

详细博客:https://blog.csdn.net/tangshiyilang/article/details/129806747

5.3、创建工程并选择如下包信息

主要包信息:spring-data-redis+spring session包

5.3、工程pom.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.txc</groupId>
    <artifactId>distributed-session</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>distributed-session</name>
    <description>distributed-session</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

5.4、配置连接Redis和springsession配置信息

store-type: redis:必须要添加这条信息,告诉程序session信息要存入到redis中。

server:
  port: 8081
spring:
  data:
    redis:
      database: 0
      host: 192.168.133.145
      port: 6379
      timeout: 5000
      password: 123456
  session:
    store-type: redis
    timeout: 3600
    redis:
      namespace: logininfo

5.5、创建UserController实现登录和查看用户信息

login:用户用户登录,必须传入username参数

getUserInfo:用于获取当前用户的登录信息

@RestController
public class UserController {
    @RequestMapping("/login")
    public String login(@RequestParam String username,
                        HttpSession session){
        System.out.println("==========login=============");
        session.setAttribute("username",username);
        return "登录成功";
    }
    @RequestMapping("/getUserInfo")
    public String getUserInfo(HttpSession session){
        return "当前登录用户=>"+session.getAttribute("username");
    }
}

5.6、在启动类通过注解开启

核心注解:@EnableRedisHttpSession

@SpringBootApplication
@EnableRedisHttpSession
public class DistributedSessionApplication {
    public static void main(String[] args) {
        SpringApplication.run(DistributedSessionApplication.class, args);
    }
}

5.7、通过浏览器访问login实现登录

请求地址:http://localhost:8081/login?username=xiaochun

5.8、登录之后查看redis中的session信息

sessionAttr:username:存放了用户登录的信息

creationTime:session:创建时间

maxInactiveInterval:最大的不活动时间

lastAccessedTime:最后的访问时间

5.9、基于IDEA启动两个工程

我们基于idea创建两个工程,模拟分布式环境,端口分别是8081和8082端口。

用户模拟用户第一次访问进入服务器1,然后访问服务器2的时候可以直接获取访问服务器1时候的用户登录信息。

5.9.1、在idea中选中edit configurations配置项目

5.9.2、选择Modify options选项

5.9.3、在下拉框中选择Add VM options

5.9.4、在输入框中输入端口信息

5.9.5、复制第一个启动项并修改名称和端口

5.9.6、分别启动两个工程

5.9.7、通过8081号端口访问login登录接口

5.9.8、通过8082号端口访问getUserInfo接口

这个时候我们发现可以直接获取到session中的信息,因为两个工程都是使用redis中的存放的session信息。

5.10、清空session信息

sesssion.invalidate();

相关推荐

  1. Redis可以用作分布式共享session解决方案

    2023-12-07 08:46:01       39 阅读
  2. 分布式websocket实时通讯session共享问题

    2023-12-07 08:46:01       32 阅读
  3. redis分布式session本地session有啥区别

    2023-12-07 08:46:01       28 阅读
  4. Redis 实现分布式Session 登录相关细节

    2023-12-07 08:46:01       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-07 08:46:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-07 08:46:01       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-07 08:46:01       82 阅读
  4. Python语言-面向对象

    2023-12-07 08:46:01       91 阅读

热门阅读

  1. 4.1 Docker 容器化和镜像管理

    2023-12-07 08:46:01       51 阅读
  2. *p++和(*p)++的区别

    2023-12-07 08:46:01       49 阅读
  3. 【使用uniapp完成微信小程序的图片下载到本机】

    2023-12-07 08:46:01       63 阅读
  4. Vue实战(十):对数组数据的拆分和分组合并

    2023-12-07 08:46:01       56 阅读
  5. 有基础转Go语言学习笔记(2. 基本数据结构篇)

    2023-12-07 08:46:01       48 阅读
  6. C++的文件读写

    2023-12-07 08:46:01       69 阅读
  7. C++11改进观察者模式

    2023-12-07 08:46:01       57 阅读
  8. [leetcode 差分数组] 拼车 M

    2023-12-07 08:46:01       58 阅读
  9. ElasticSearch 查询优化手段有哪些?

    2023-12-07 08:46:01       50 阅读
  10. 持续集成部署-k8s-高级调度-亲和力

    2023-12-07 08:46:01       40 阅读
  11. 图论|841钥匙和房间

    2023-12-07 08:46:01       60 阅读