Springboot实现多服务器session共享

作者:New_Yao 时间:2022-09-06 13:58:34 

本文实例为大家分享了springboot实现多服务器session共享的具体代码,供大家参考,具体内容如下

环境:

springboot:2.0.4
redis:3.2.100
jdk:1.8
eclipse:4.9.0

1.原理

正常情况下,HTTPSession是通过servlet容器创建并管理的,创建成功后都保存在内存中,如果开发者需要对项目进行横向拓展搭建集群,那么可以用一些硬件和软件工具来做负载均衡,此时,来自同一用户的HTTP请求有可能会被发送到不同的实例上去,如何保证各个实例之间的Session同步就成为了一个必须解决的问题,Springboot提供了自动化session共享配置,它结合redis非常方便的解决了这个问题。使用Redis解决session共享的原理非常简单,就是把原本储存在不同服务器上的session拿出来放到一个独立的服务器上,可以参考下图来理解

Springboot实现多服务器session共享

当一个请求到达Nginx服务器上时,首先请求分发,假设请求被server2处理了,server2在处理请求时,无论存储还是读取session的操作,都是去操作session服务器而不是自身内存中的session,其他server也是如此,这样就实现了session共享!

2.如何实现

关于Nginx和Redis的配置,本文就不再详细介绍,网上教程也有很多。这里使用手动直接访问两个端口模拟nginx反向代理。

2.1首先创建一个springboot项目,全部的pom.xml配置如下:

除了Redis依赖之外,这里还需要提供spring-session-data-redis依赖,Spring Session可以做到透明的替换掉应用中的Session容器。


<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>cn</groupId>
<artifactId>session-two</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>session-two</name>
<url>http://maven.apache.org</url>

<properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-redis</artifactId>
 <exclusions>
 <exclusion>
  <groupId>io.lettuce</groupId>
  <artifactId>lettuce-code</artifactId>
 </exclusion>
 </exclusions>
</dependency>
<dependency>
 <groupId>redis.clients</groupId>
 <artifactId>jedis</artifactId>
</dependency>

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
 <groupId>org.springframework.session</groupId>
 <artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>4.12</version>
 <scope>test</scope>
</dependency>
</dependencies>
<build>
 <plugins>
 <plugin>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-maven-plugin</artifactId>
 </plugin>
</plugins>
</build>
</project>

2.2 application.properties中进行redis配置


spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.max-wait=-1ms
spring.redis.jedis.pool.min-idle=0

2.3 创建controller测试


import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

@Value("${server.port}")
String port;
@PostMapping("save")
public String saveName(String name,HttpSession session ) {
session.setAttribute("name", name);
return port;
}

@GetMapping("get")
public String saveName(HttpSession session ) {
return port+":"+session.getAttribute("name").toString();
}
}

这里提供了两个接口,一个是save用来向session中保存数据,一个是get用来从session中获取数据,这里注入了项目端口server.prot主要是用来显示是那个服务器提供的服务(Nginx下方便查看),虽然我们在这里操作的是Httpsession,但是其实Httpsession容器已经被透明的替换掉了,真正的session此时存储在redis服务器上。

3.进行测试

3.1将项目打成jar包,然后打开两个命令提示框,分别执行如下两个命令启动项目


java -jar session-two-0.0.1-SNAPSHOT.jar --server.port=81
java -jar session-two-0.0.1-SNAPSHOT.jar --server.port=82

3.2使用Postman测试

3.2.1 访问81服务器并且设置name为张三

Springboot实现多服务器session共享

3.2.2 访问82服务器获取session中保存的name

Springboot实现多服务器session共享

至此,一个简单的demo就完成了

来源:https://blog.csdn.net/New_Yao/article/details/89887455

标签:springboot,服务器,session
0
投稿

猜你喜欢

  • java判断字符串是否有逗号的方法

    2021-11-03 08:01:23
  • java实现操作系统的短进程作业调度示例分享

    2022-05-30 21:02:19
  • Docker 存储驱动详细介绍

    2023-12-21 03:18:34
  • Spark内存调优指南

    2022-07-28 09:22:25
  • Android编程将Activity背景设置为墙纸的简单实现方法

    2022-01-13 14:27:42
  • Java中常见的5种WEB服务器介绍

    2022-08-02 08:45:50
  • SpringSecurity Jwt Token 自动刷新的实现

    2022-04-28 18:49:45
  • C#实现窗体淡入淡出效果的方法总结

    2021-05-28 08:23:37
  • 解析Silverlight调用WCF/Rest异常的解决方法

    2021-08-19 07:41:37
  • Android 判断日期是否在一年以内的算法实例

    2023-03-22 06:04:13
  • java判断http地址是否连通(示例代码)

    2023-08-05 03:24:05
  • Android Canvas的drawText()与文字居中方案详解

    2021-10-20 00:33:32
  • springboot为异步任务规划自定义线程池的实现

    2022-12-05 01:13:02
  • Java单例模式的线程安全,饿汉和懒汉模式详解

    2022-05-31 16:12:08
  • 用C#将图片保存至Oracle BLOB字段中的方法

    2023-06-12 01:29:16
  • 一文理解kafka rebalance负载均衡

    2022-12-02 10:35:22
  • TextView实现跑马灯效果 就这么简单!

    2023-06-25 18:42:24
  • android自定义View实现圆环颜色选择器

    2023-11-07 19:16:02
  • flutter Bloc 实现原理示例解析

    2023-07-18 08:00:39
  • C#使用Unity实现剪刀石头布游戏

    2023-03-01 06:30:18
  • asp之家 软件编程 m.aspxhome.com