javascript
SpringBoot笔记:SpringBoot2.3集成SpringSession+nginx+redis实现session共享
文章目錄
- Spring Session介紹
- Redis集成
- yml配置
- 依賴添加
- redis存值查看
- 登錄服務器查看redis的值
- 查詢所有"spring:session:"開頭的keys
- SpringBoot默認創建的key
- nginx集成
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集成
yml配置
springboot集成Redis可以參考《SpringBoot筆記:SpringBoot2.3集成Redis Cluster集群配置》
這里就添加如下配置,使用redis存儲session:
依賴添加
在引入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模式,配置如下:
前面我們可以看到這個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配置如下:
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臺機器都是共享的。
總結
以上是生活随笔為你收集整理的SpringBoot笔记:SpringBoot2.3集成SpringSession+nginx+redis实现session共享的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringBoot笔记:SpringB
- 下一篇: SpringBoot笔记:SpringB