SpringBoot笔记:SpringBoot2.3集成SpringSession+nginx+redis实现session共享

Spring Session介绍

在默认情况下,SpringBoot使用Tomcat服务器的Session实现,编写一个例子测试:

@RestController
@RequestMapping("/session")
@Slf4j
public class SpringSessionController {
    @RequestMapping("/putsession")
    public String putSession(HttpServletRequest request) {
        HttpSession session = request.getSession();
        log.info("sessionClass为:{}", session.getClass());
        log.info("sessionId为:{}", session.getId());
        session.setAttribute("user", "i am leo825");
        return "putsession success";
    }
}

通过访问:http://localhost:8080/springsession-demo/session/putsession,控制台输出为:

2021-01-13 23:18:53.853 [http-nio-8080-exec-1] INFO  com.demo.controller.SpringSessionController:19 - sessionClass为:class org.apache.catalina.session.StandardSessionFacade
2021-01-13 23:18:53.854 [http-nio-8080-exec-1] INFO  com.demo.controller.SpringSessionController:20 - sessionId为:23813E88BC0FA799EB883F3D23F9CB15

可以看到,Session管理是通过Tomcat提供的class org.apache.catalina.session.StandardSessionFacade实现的,
配置文件yml中添加如下内容:

spring:
  session:
    store-type: redis

其中,spring.session.store-type有以下值:

  1. redis :Sessio数据存放Redis中。
  2. jdbc:会话数据存放在数据库中,默认情况下SPRING_SESSION表存放Session基本信息,如sessionId、创建时间、最后一次访问时间等,SPRING_SESSION_ATTRIBUTES表存放了session数据,ATTRIBUTE_NAME列保存了Session的Key,ATTRIBUTE_BYTES列以字节形式存放了Session的Value,Spring Session会自动创建这两张表。
  3. hazelcast:Session数据存放到Hazelcast。
  4. None:禁用Spring Session功能。

Redis集成

yml配置

springboot集成Redis可以参考《SpringBoot笔记:SpringBoot2.3集成Redis Cluster集群配置
这里就添加如下配置,使用redis存储session:

spring:
  session:
    store-type: redis

依赖添加

在引入spring-boot-starter-data-redis的依赖的同时,添加spring-session-data-redis依赖

		<dependency>
			<groupId>org.springframework.session</groupId>
			<artifactId>spring-session-data-redis</artifactId>
		</dependency>

redis存值查看

测试代码仍然是上面的测试代码,现在进行测试。启动项目,并访问http://localhost:8080/springsession-demo/session/putsession,控制台输出为:

2021-01-13 23:35:55.827 [http-nio-8080-exec-1] INFO  o.a.c.c.C.[.[localhost].[/springsession-demo]:173 - Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-01-13 23:35:55.910 [http-nio-8080-exec-1] INFO  com.demo.controller.SpringSessionController:19 - sessionClass为:class org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper
2021-01-13 23:35:55.911 [http-nio-8080-exec-1] INFO  com.demo.controller.SpringSessionController:20 - sessionId为:31115fe8-2169-4099-879f-090fbb6edc44

登录服务器查看redis的值

redis-cli -c -p 7001 -a admin@2021

查询所有"spring:session:"开头的keys

keys spring:session:*

输出结果如下:

192.168.223.131:7003> keys spring:session:*
1) "spring:session:expirations:1610553960000"
2) "spring:session:sessions:expires:31115fe8-2169-4099-879f-090fbb6edc44"

会话信息存放在"spring:session:sessions:"开头的key中,31115fe8-2169-4099-879f-090fbb6edc44代表一个会话id,"spring:session:sessions:31115fe8-2169-4099-879f-090fbb6edc44"是一个Hash数据结构,可以用Redis HASH相关命令来查看数据:

hgetall "spring:session:sessions:31115fe8-2169-4099-879f-090fbb6edc44"

输出结果如下:

192.168.223.131:7003> hgetall "spring:session:sessions:31115fe8-2169-4099-879f-090fbb6edc44"
-> Redirected to slot [5335] located at 192.168.223.131:7001
1) "maxInactiveInterval"
2) "\xac\xed\x00\x05sr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\a\b"
3) "creationTime"
4) "\xac\xed\x00\x05sr\x00\x0ejava.lang.Long;\x8b\xe4\x90\xcc\x8f#\xdf\x02\x00\x01J\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x01v\xfc?\xc5\xcd"
5) "lastAccessedTime"
6) "\xac\xed\x00\x05sr\x00\x0ejava.lang.Long;\x8b\xe4\x90\xcc\x8f#\xdf\x02\x00\x01J\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x01v\xfcc\x9e\xe9"
7) "sessionAttr:user"
8) "\xac\xed\x00\x05t\x00\x0bi am leo825"

使用以下命令查看Session中user的信息:

HMGET "spring:session:sessions:31115fe8-2169-4099-879f-090fbb6edc44" sessionAttr:user

输出结果:

192.168.223.131:7001> HMGET "spring:session:sessions:31115fe8-2169-4099-879f-090fbb6edc44" sessionAttr:user
1) "\xac\xed\x00\x05t\x00\x0bi am leo825"

SpringBoot默认创建的key

上面的例子中sessionAttr:user是Spring Session 中存入Redis的key值,sessionAttr:是其前缀,user是我们在会话中设置的key,其他SpringBoot默认创建的key有:

  • creationTime,创建时间
  • maxInactiveInterval,指定过期时间(秒)
  • lastAccessedTime,上次访问时间。
  • sessionAttr,以“sessionAttr:”为前缀的会话信息,比如:sessionAttr:user.
    注意:
    Spring Session 的Redis实现并不是每次通过Session类获取会话信息或者保存的时候都会调用Redis操作,它会先尝试从内部HashMap读取值,如果没有,才调用Redis的HMGET操作。同样,当保存会话的时候也没有立即调用Redis操作,二十先保存到HashMap中,等待服务请求结束后在即将变化的值使用HMSET更新。如果你项在保存会话操作后立即更新到Redis中,需要配置成IMMEDIATE模式,配置如下:
spring.session.redis.flushMode=IMMEDIATE

前面我们可以看到这个key

"spring:session:sessions:expires:31115fe8-2169-4099-879f-090fbb6edc44"

着是因为Redis会话国企并没有直接使用在session:sessions:key变量上,而是专门在session:sessions:expires:key上,当此Key过期后,会自动清除对应的会话信息。可以使用ttl命令查看过期时间:

ttl "spring:session:sessions:expires:31115fe8-2169-4099-879f-090fbb6edc44"

输出结果如下:

192.168.223.131:7001> ttl "spring:session:sessions:expires:31115fe8-2169-4099-879f-090fbb6edc44"
-> Redirected to slot [14958] located at 192.168.223.131:7003
(integer) 269

还有269秒就过期了

nginx集成

可以先参考《CentOS7下安装nginx1.99》文章中nginx配置
其中nginx配置如下:

	# nginx的upstream配置,采用轮询配置
	upstream bakend {
		server hadoop-master:8001;
		server hadoop-master:8002;
		server hadoop-master:8003;
	}

sever中添加我们的上下文路径:

	# springboot-session测试项目
	location /springsession-demo {
       proxy_pass http://bakend;
    }

我们这里使用三台机器模拟集群情况。将我们的测试代码达成jar包,然后在服务器上启动:

nohup java -jar springboot-session-1.0-SNAPSHOT.jar --server.port=8001 &
nohup java -jar springboot-session-1.0-SNAPSHOT.jar --server.port=8002 &
nohup java -jar springboot-session-1.0-SNAPSHOT.jar --server.port=8003 &

访问nginx测试地址:http://hadoop-master/springsession-demo/session/putsession,访问3次,可以看到3个服务器的开始轮询输出以下日志:

2021-01-14 00:21:49.280 [http-nio-8003-exec-1] INFO  o.a.c.c.C.[.[localhost].[/springsession-demo]:173 - Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-01-14 00:21:49.568 [http-nio-8003-exec-1] INFO  com.demo.controller.SpringSessionController:19 - sessionClass为:class org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper
2021-01-14 00:21:49.569 [http-nio-8003-exec-1] INFO  com.demo.controller.SpringSessionController:20 - sessionId为:425dead7-57b0-4552-a1fe-774b1e11184d

如果停掉其中一台服务,这里把端口为8003的停掉了:

[root@hadoop-master springboot-port8003]# ps -ef|grep springboot-session-1.0-SNAPSHOT.jar 
root       4318   3340  2 00:11 pts/1    00:00:19 java -jar springboot-session-1.0-SNAPSHOT.jar --server.port=8003
root       4363   3340  3 00:12 pts/1    00:00:22 java -jar springboot-session-1.0-SNAPSHOT.jar --server.port=8002
root       4384   3340  3 00:12 pts/1    00:00:23 java -jar springboot-session-1.0-SNAPSHOT.jar --server.port=8001
root       4734   4521  0 00:24 pts/3    00:00:00 grep --color=auto springboot-session-1.0-SNAPSHOT.jar
[root@hadoop-master springboot-port8003]# kill -9 4318
[root@hadoop-master springboot-port8003]# ps -ef|grep springboot-session-1.0-SNAPSHOT.jar 
root       4363   3340  3 00:12 pts/1    00:00:22 java -jar springboot-session-1.0-SNAPSHOT.jar --server.port=8002
root       4384   3340  3 00:12 pts/1    00:00:23 java -jar springboot-session-1.0-SNAPSHOT.jar --server.port=8001
root       4736   4521  0 00:24 pts/3    00:00:00 grep --color=auto springboot-session-1.0-SNAPSHOT.jar

然后继续访问nginx测试地址:http://hadoop-master/springsession-demo/session/putsession,发现服务仍能够正常运行,因为session信息存在于redis中对于3台机器都是共享的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leo825...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值