Springboot实现多服务器session共享
本文实例为大家分享了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拿出来放到一个独立的服务器上,可以参考下图来理解
当一个请求到达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就完成了
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。