SpringBoot應用系列文章
本文主要講怎麼在spring boot應用裏頭搭建分佈式會話。對於分佈式的應用來講,用戶的會話管理一般有Session Stick,Session複製,Session集中管理,基於Cookie管理四種方式。各自點評一下:java
須要某個用戶的會話與某臺服務器想綁定,有點耦合redis
每臺服務器都有所有的會話信息,會話同步須要時間,另外每臺服務器都有全量數據也是個問題spring
單獨的會話服務,不須要同步,可是一樣有網絡開銷,另外須要處理單點問題docker
把session數據放在cookie中,增長網絡載荷,另外也存在安全問題。
本文主要關注集中式Session方面,其實現主要有兩種方案,一種是容器相關的,好比基於Tomcat的tomcat-redis-session-manager以及基於Jetty的jetty-session-redis等等;另外一種就是容器解耦的,就是今天要集成的Spring-Session。shell
參考我以前寫的文章《docker搭建redis集羣》segmentfault
#1.3.0.RELEASE之後的版本使用 server.session.timeout=10 #server.session-timeout=10 #1.2.7.RELEASE以及以前的版本使用 spring.redis.host=192.168.99.100 #這個就是docker machine default虛擬機的ip #spring.redis.password=secret spring.redis.port=6379
@RestController @RequestMapping("/session") public class HelloController { @RequestMapping("/uid") String uid(HttpSession session) { UUID uid = (UUID) session.getAttribute("uid"); if (uid == null) { uid = UUID.randomUUID(); } session.setAttribute("uid", uid); return session.getId(); } }
訪問http://localhost:8080/session/uid緩存
d1b1cc0c-519e-431a-973c-6c742a014660
docker@default:~$ docker exec -it redis-master /bin/bash root@86784a615b3d:/data# redis-cli keys '*' 1) "spring:session:sessions:d1b1cc0c-519e-431a-973c-6c742a014660" 2) "spring:session:expirations:1453639380000"
至關於tomcat
SADD spring:session:expirations:<expire-rounded-up-to-nearest-minute> <session-id> EXPIRE spring:session:expirations:<expire-rounded-up-to-nearest-minute> 1800
expirations:1453639380000表示該session將在1453639380000這個時刻被刪除。
1800表示1800秒,即30分鐘,默認30分鐘過時。安全
127.0.0.1:6379> hkeys spring:session:sessions:d1b1cc0c-519e-431a-973c-6c742a014660 1) "sessionAttr:uid" 2) "lastAccessedTime" 3) "maxInactiveInterval" 4) "creationTime" 127.0.0.1:6379> hget spring:session:sessions:d1b1cc0c-519e-431a-973c-6c742a014660 sessionAttr:uid "\xac\xed\x00\x05sr\x00\x0ejava.util.UUID\xbc\x99\x03\xf7\x98m\x85/\x02\x00\x02J\x00\x0cleastSigBitsJ\x00\x0bmostSigBitsxp\xa0E\xe3\x1d\xf9K\xecW6\xcf\xbc\xfbU\x13M\x88" 127.0.0.1:6379> hget spring:session:sessions:d1b1cc0c-519e-431a-973c-6c742a014660 lastAccessedTime "\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\x01Rs\x8d\x12b"
30分鐘事後已通過期bash
127.0.0.1:6379> hget spring:session:sessions:d1b1cc0c-519e-431a-973c-6c742a014660 creationTime --raw (error) ERR wrong number of arguments for 'hget' command 127.0.0.1:6379> keys * (empty list or set)
再刷新網頁獲得新的sessionid
3ed21473-c5ee-41e1-b64e-35b0737c0365
設置的timeout沒有生效,都以1800秒爲準了。經驗證,得這樣設置纔有效:
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 60) //1分鐘失效