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分钟失效