session用于服务器和浏览器在建立会话后创建的一个唯一凭证,当多个用户访问同一个服务,就会创建多个session在服务器端保存,这些session通过sessionManager来管理,每个session相当于一个map可以设置多个值存储当前浏览器会话设置的信息,session创建后会返回给浏览器唯一凭证sessionId,它会保存在cookier当中的请求路径域名下,以JSESSION为key保存sessionid值,当下次请时会携带cookie下的指定地址下cookie的数据到服务器中查询session是否存在,存在判断是否登陆并获取登陆的用户信息,当浏览器关闭后就cookie就会失效,用户重新登陆继续会话,服务端的session默认保留30分钟,当你不适用上次的seeion后会30分钟会销毁,这个时间可以在web.xml中设置时间,主动失效要么服务器关闭要么使用invalidate()才会失效,或者等带指定的时间失效,sessionManager帮我们管理,session会默认在指定的域名下工作,跨域名共享数据就会失败。
这些在单体项目中跨请求地址可以获取共享的数据,但在多体项目携带session到其他服务中就会完全失效。seesion工作原理就好比办理银行卡,第一次使用身份证建立会话,银行返回给你一个卡号,你下次拿着卡号,银行直接可以根据卡号和当前保存的卡号系统就能直接工作,卡号就是存在浏览器cookie中的sessionId,卡号系统就是管理的session,每个人都可以申请到自己的session,根据seesion直接会话。
解决方案:1多个微服务对session同步复制,不建议采取因为复制开销大网络带宽受影响 2使用一致性hash对ip或者域名hash获取整数然后再根据相同服务的数量取余操作,那么请求负载到只有一个相同的服务,当水平扩容的时候不一致,session也会有失效时间不会有所影响 3使用公共存储介质,将共享数据存储在mysql/redis中,当跨服务时可以直接让当前服务查询mysq或redis存的session信息,后端统一存储session比较安全,容易扩展,缺点有网络交互连接redis。总结解决方案可以使用一致性hash或后端统一处理,一致性hash比较麻烦,支持第二种方案。
统一存储session解决方案,spring提供springSession框架,session共享问题解决-不同服务,子域名session共享,子域session共享,如a.bowen.com获得session后可以在请求页看到cookie保存的信息,在b.bowen.com看不到上一个保存的cookie信息,要共享a的cookie就要修改a的作用域domain的地址比如将的实体作用域a,bowen.com修改为.bowen.com在b.bowen.com地址页检查cookie就会存在相同的cookie信息。那么浏览器就能跨不同的域名共享这个session,担是不能在浏览器中修改,在服务器第一次发放session时就应该扩大session的作用域,让浏览器端不同域名下符合cookie匹配的路径都能共享cookie,子域发放的seesion所以的父域名都可以使用。
httpServletResponse.addCookie(new Cookie("JSESSION",data).setDomain(" ")) spriingSession
实现的方式如此,自己添加较为麻烦。这也客户端的cookie就能共享,请求服务携带上cookie去redis查询数据。
整合springsession引入依赖:
<!-- 整合springsession --><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId></dependency>
配置文件配置属性值,启动类开启springSession功能。