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();