分布式session

391 阅读1分钟

常见的会话解决方案

  • 粘性会话,loadbalance实现,尽量让同一个用户的请求,落在同一台机器上,分布式session变成了单机session
  • 会话复制,集群拥有相同的请求信息,不推荐
  • 集中会话,jdbc/redis集中存储会话,取出jsessionid相同的会话

Spring Session

  • 实现集中会话,简化集群中用户session的管理
  • 无需绑定容器特定解决方案
  • 支持的存储:redis/mongodb/jdbc/hazelcast
  • 实现原理:通过定制的HttpServletRequest返回定制的HttpSession,这个session就可以屏蔽后端存储的各种差异,redis/jdbc都是相同的对外暴露的接口
  • 核心类:
    SessionRepositoryRequestWrapper: 封装了request
    SessionRepositoryFilter: getSession/commitSession等
    DelegatingFilterProxy

基于redis的HttpSession

  • 依赖:spring-session-data-redis
  • 基本配置:@EnableRedisHttpSession
  • 提供RedisConnectionFactory
  • 实现AbstractHttpSessionApplicationInitializer,配置DelegatingFilterProxy

spring boot对spring session的支持

依赖:
spring-session-core
spring-session-data-redis
spring-boot-starter-data-redis
spring-boot-starter-web

application.properties

  • spring.session.store-type=redis
  • spring.redis.host=
  • spring.session.timeout=
  • spring.servlet.session.timeout=
  • spring.session.redis.flush-mode=on-save
  • spring.session.redis.namespace=spring:session

注:从request中取出session,检查name字段,若为空,进行赋值

docker docker start redis
docker exec -it redis redis-cli
keys *
type (key)
HGETALL (key)

测试/hello?name=spring 返回hello spring
Request Headers Accept:
Response Headers Set-Cookie:SESSION=

进一步测试/hello?name=s 返回依然是hello spring,然后重启服务器,因为会话信息是保存在redis中的,所以不会丢失,故对于相同的sessionId,还是可以取得相同的session。即重新run,服务器重启后,还是hello spring,因为这本质是spring session实现的集中会话,分布式会话管理