问题:
第一次访问服务器,登录,登陆成功了用户保存到session中,并会返回jsessionid给浏览器cookie
以后访问都会带上cookie,用于获取服务器中的session数据
浏览器关闭的话,就会清除cookie,你也可以设置过期时间
BUT分布式的情况下,其作用域就只能在本域名之下,不可跨域名共享
BUT分布式的情况下,其作用域就只能在当前服务之下,多服务之间(不同端口的服务),也无法共享
解决方式1:session复制
缺点:session同步需要网络带宽,也会造成延迟
解决方式2:在客户端存储,也就是直接存到cookie中
缺点:每次请求要携带大量cookie浪费带宽,并且cookie最长只有4k,并且cookie可能造成泄露或篡改
解决方式3:hash一致性
只需要改nginx配置,利用nginx负载均衡机制。具体就是根据访问的人的信息(ip)来得到hash值并分配到对应的服务器。因为hash值分布均衡。
缺点:session依然存在服务器中,单一服务器重启后session丢失,需要重新登录。另外服务器扩展的话需要rehash,session也需要重新分布。但是缺点总体问题还不是很大。
解决方式4:统一存储session
主要是用redis来统一存储session数据,而不同的服务根据负载均衡来分配去redis取。
这样服务器比较平均,redis也足够处理。这样服务可以随意扩展,反正都需要到redis里取
缺点:增加了网络调用,主要性能瓶颈在调用redis那一步
SpringSession整合
https://docs.spring.io/spring-session/docs/2.3.x/reference/html5/
依赖:
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
配置:
spring.session.store-type=redis
过期时间配置:
server.servlet.session.timeout=30m
redis连接信息:
spring.redis.host=localhost
spring.redis.port=6379
配置类:
@EnableRedisHttpSession
public class SpringSessionConfig {
@Bean
public LettuceConnectionFactory connectionFactory() {
return new LettuceConnectionFactory();
}
}
用的时候:
public String weibo(HttpSession session)
session.setAttribute("loginUser", respVo);
记得序列化,否则会有序列化问题(默认JDK序列化):
public class MemberRespVo implements Serializable
成功后,redis可以看到数据

子域名session应用到二级父域名?
不一定,可以在对应的三级子域名的项目那里,一样配置springsession和redis,还有配置类同上。以此,对方服务就能拿到session数据了
然后,如果双边服务都是如上放同一个vo对象,那么需要做个common包同时引用,才能保证两边都能获取数据并序列化
问题是如何跨域名放cookie?
参考文档:设置cookie的时间域名等等
https://docs.spring.io/spring-session/docs/2.3.x/reference/html5/#api-cookieserializer
参考文档:设置Redis用Json序列化
https://github.com/spring-projects/spring-session/blob/2.3.3.RELEASE/spring-session-samples/spring-session-sample-boot-redis-json/src/main/java/sample/config/SessionConfig.java
具体:(注意多个服务都这样配)
@EnableRedisHttpSession
@Configuration
public class SpringSessionConfig implements BeanClassLoaderAware {
@Bean
public CookieSerializer cookieSerializer(){
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
// cookieSerializer.setCookieMaxAge();
cookieSerializer.setDomainName("gulimall.com");//放大域名
cookieSerializer.setCookieName("GULISESSION");//cookie的key名
return cookieSerializer;
}
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
//因为通用能用泛型的?
return new GenericJackson2JsonRedisSerializer();
}
private ClassLoader loader;
/*
* (non-Javadoc)
*
* @see
* org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader(java.lang
* .ClassLoader)
*/
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.loader = classLoader;
}
}
