SpringBoot分布式会话
对于当前服务器群集,用户登录会话状态的保存也从独立更改为分布式请求。 下面详细介绍了几种分布式会话存储方案。
会话复制—在支持会话复制的服务上运行,同步会话并维护会话一致性
方案: tomcat-redis-session-manager
session粘滞:强制将session分发到每台服务器
方案:负载平衡
cookie存储会话:将会话id保存到cookie (不安全、cookie易被盗且可以保存不重要的数据)。
集中会话管理- -将用户的会话存储在单个或集群服务器缓存中,所有web服务器从其中检索会话以实现会话共享
方案: Redis存储cookie,该cookie存储用户生成的会话id或会话id
这里只说明第4个方案,使用最稳定
Redis创建缓存持久化存储会话
Redis保存cookie,并保存用户生成的uuid。 (token作为会话id )。
cookie名称和过期日期
publicstaticfinalstringcookie _ name _ token=' token ';
私密静态财务Ex=3600;
创建cookie并保存到redis
私有密钥用户{
String token=UUIDUtil.uuid (;
redisservice.set(Token,user ); 使用redis,以token为键,即使使用存储user的值jedis自身安装的值,也可以使用redisTemplate
cookie cookie=new cookie (cookie _ name _ token,token ); 将cookie命名为token
cookie.setmaxage(ex; //设定有效期限
cookie.setpath((/);
response.addcookie(cookie );
返回令牌;
}
uid作为会话id生成工具
公共类用户实用工具{
公共静态字符串uuid
return UUID.randomUUID ().toString );
}
}
使用Shiro集成的crazy-cake (使用Redis保存会话id ) ) ) ) ) ) ) ) ) ) )。
shiro是一个Web安全框架,用于登录验证、用户验证、使用简单的spring-security、继承session和cookie分布式存储
高速缓存
使用缓存存储会话(单服务器使用EhCacheManager )
但是,在分布式系统中,对于服务器群集,如果EhCacheManager无法解析数据共享(多次询问数据库),则选择使用redis作为缓存
Redis实现了shiro缓存
要与session分散共享授权信息,必须将session和授权持久化到数据库或缓存shiro群集。 这是为了防止对数据库的查询重复
自定义实现类:或使用开源CrazyCakeShiro-Redis实现优秀的工具
RedisSessionDAO可以继承EnterpriseCacheSessionDAO实现session控制
RedisCache继承Cache类并实现特定的redis操作缓存(remove、get、set和keys )
RedisCacheManager实现界面CacheManager的getCache获取RedisCache并交给securityManager管理
使用并发映射管理数据和缓存,以便更高效
在ShiroConfig配置类中将会话管理器传递给DefaultWebSecurityManager进行管理
@Bean
publicdefaultwebsessionmanagersessionmanager {
efaultwebsessionmanagersessionmanager=newdefaultwebsessionmanager (;
//session时间
session manager.setglobalsessiontimeout (redis config ).getTimeout );
//删除无效的会话
会话管理器. setdeleteinvalidsessions (true;
log.info (会话管理器注入成功);
session manager.setsessionidcookie (cookie ) );
//sessionDao必须将session和授权持久化到数据库或缓存shiro群集,才能与session分散共享授权信息。 这是为了防止对数据库的查询重复
会话管理器. setsessiondao (redissessiondao );
返回会话管理器;
}
向会话管理器注入cookie存储jsessionId
@Bean
公共简单cookie cookie (
simplecookiecookie=newsimplecookie (jsessionid );
cookie.sethttponly(true;
cookie.setpath((/);
返回套接字;
}
向会话管理器注入redisSessionDao,负责会话的持续化
@Bean
publicredissessiondaoredissessiondao (
redissessiondaoredissessiondao=newredissessiondao (;
redissessiondao.setredismanager (redis manager ) );
redissessiondao.setsessionidgenerator (会话id生成器();
返回就绪型会话;
}