使用srpingboot实现多服务器session共享

14 篇文章 0 订阅
2 篇文章 0 订阅

环境:
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拿出来放到一个独立的服务器上,可以参考下图来理解
在这里插入图片描述
当一个请求到达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为张三

在这里插入图片描述

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

在这里插入图片描述
至此,一个简单的demo就完成了

附:码云Demo

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值