一:session问题
- 1.不能跨域名进行共享
- 2.同一个服务,复制多份,session不同步问题
二:session共享问题解决
1.session复制(不采用)
优点:
- web-server(Tomcat)原生支持,只需要修改配置文件
缺点:
- session同步需要数据传输,占用大量网络带宽,降低了服务器群的业务处理能力。
- 任意一台web-server保存的数据都是所有web- server的session总和,受到内存限制无法水平扩展 更多的web-server
- 大型分布式集群情况下,由于所有web-server都全 量保存数据,所以此方案不可取。
2.客户端存储(不采用)
优点:
- 服务器不需存储session,用户保存自己的 session信息到cookie中。节省服务端资源
缺点:都是缺点,这只是一种思路。
- 每次http请求,携带用户在cookie中的完整信息, 浪费网络带宽 ,不安全
- session数据放在cookie中,cookie有长度限制 4K,不能保存大量信息
- session数据放在cookie中,存在泄漏、篡改、 窃取等安全隐患
3.hash一致性
优点:
• 只需要改nginx配置,不需要修改应用代码
• 负载均衡,只要hash属性的值分布是均匀的,多台 web-server的负载是均衡的
• 可以支持web-server水平扩展(session同步法是不行 的,受内存限制)
缺点:
• session还是存在web-server中的,所以web-server重 启可能导致部分session丢失,影响业务,如部分用户 需要重新登录
• 如果web-server水平扩展,rehash后session重新分布, 也会有一部分用户路由不到正确的session
• 但是以上缺点问题也不是很大,因为session本来都是有有 效期的。所以这两种反向代理的方式可以使用
4.统一存储(推荐)
优点:
• 没有安全隐患
• 可以水平扩展,数据库/缓存水平切分即 可
• web-server重启或者扩容都不会有 session丢失
缺点:
• 增加了一次网络调用,并且需要修改应 用代码;如将所有的getSession方法替 换为从Redis查数据的方式。redis获取数 据比内存慢很多
• 上面缺点可以用SpringSession完美解决
三:SpringBoot整合SpringSession——完成session共享
1.引入依赖
<!--引入springSession-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
2.配置文件配置session类型
#redis的连接信息
spring.redis.host127.0.0.1
spring.redis.port=6389
#session的类型
spring.session.store-type=redis
#session的过期时间
server.servlet.session.timeout=30m
3.在主启动类添加@EnableRedisHttpSession
//整合redis作为session存储
@EnableRedisHttpSession
四:子域session共享问题
1.新建GulimailSessionConfig配置类
@Configuration
public class GulimailSessionConfig {
@Bean
public CookieSerializer cookieSerializer(){
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
//指定作用域
cookieSerializer.setDomainName("");
//设定cookie名字
cookieSerializer.setCookieName("GULISESSION");
return cookieSerializer;
}
/**
* 设置序列化机制
* @return
*/
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer(){
return new GenericJackson2JsonRedisSerializer();
}
}
五:SpringSession核心原理
1.@EnableRedisHttpSession注解原理
1)EnableRedisHttpSession导入了RedisHttpSessionConfiguration
给容器中添加了组件
- RedisOperationsSessionRepository,redis操作session的增删改查
- SessionRepositoryFilter:session存储的过滤器,每个请求就需要经过过滤器。创建的时候就自动创建了。
2.核心代码
- 放行包装之后的request和response应用到执行链。
- 以后获取session:wrappedRequest.getSession()中获取
- session会自动延期
六:用户名密码登录整合session
1.代码实现
@PostMapping("/login")
public String login(UserLoginVO vo, RedirectAttributes redirectAttributes, HttpSession session){
//远程登录
R r = memberFeignService.login(vo);
if(r.getCode() == 0){
//往session中去保存数据
MemberRespVo data = r.getData(new TypeReference<MemberRespVo>(){});
session.setAttribute(AuthServerConstant.LOGIN_USER,data);
//成功就去首页
return "redirect:http://127.0.0.1:10000";
} else {
Map<String, String> errors =new HashMap<>();
errors.put("mag",r.getData(new TypeReference<String>(){}));
redirectAttributes.addFlashAttribute("errors",errors);
//失败就去登录页
return "redirect:http://127.0.0.1:20000/login.html";
}
}
2.登录的时候先看session中有没有用户信息,如果有就不需要登录了。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84090.html