SpringBoot應用之分佈式會話

SpringBoot應用系列文章

本文主要講怎麼在spring boot應用裏頭搭建分佈式會話。對於分佈式的應用來講,用戶的會話管理一般有Session Stick,Session複製,Session集中管理,基於Cookie管理四種方式。各自點評一下:java

  • Session Stick

須要某個用戶的會話與某臺服務器想綁定,有點耦合redis

  • Session複製

每臺服務器都有所有的會話信息,會話同步須要時間,另外每臺服務器都有全量數據也是個問題spring

  • Session集中管理

單獨的會話服務,不須要同步,可是一樣有網絡開銷,另外須要處理單點問題docker

  • 基於Cookie管理

把session數據放在cookie中,增長網絡載荷,另外也存在安全問題。
本文主要關注集中式Session方面,其實現主要有兩種方案,一種是容器相關的,好比基於Tomcat的tomcat-redis-session-manager以及基於Jetty的jetty-session-redis等等;另外一種就是容器解耦的,就是今天要集成的Spring-Session。shell

配置redis集羣

參考我以前寫的文章《docker搭建redis集羣segmentfault

新建項目

圖片描述

配置application.properties

#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

測試Controller

@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

查看redis

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分鐘過時。安全

看看session對象

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分鐘失效
相關文章
相關標籤/搜索