分布式Session共享
概念
不同进程之间的session共享访问。
解决了分布式系统或者系统集群部署时出现的问题:web容器(如tomcat)管理的session都存放于本地内存中无法共享,用户每次访问的服务器可能都不一样,因此出现服务器不能识别用户、用户登录状态失效等。
解决方案:
方案一:黏性session
NGINX等负载均衡网关,可以通过hash映射等方式,保证相同用户的请求会转发到同一台服务器。
优点:简单高效,易实施。
缺点:存在大量请求转发到单点服务器极端情况导致负载均衡失效;单点故障导致用户session丢失。
方案二:tomcat集群session复制
Tomcat提供集群环境下的session复制功能,以达到session共享。
优点:无开发工作量。
缺点:session复制会消耗大量服务器资源,只能应用于小规模的集群。
方案三:Spring session + redis(推荐)
Spring session可以接管web容器的session管理,并可以将session 数据存放于redis等第三方存储。
优点:Spring boot/cloud项目无缝集成;可存储海量session数据;可以利用redis提供的持久化保证宕机恢复、服务升级重启用户session不丢失;很好的支持服务在线扩容!
缺点:Spring session没有多语言版本,限制了微服务框架下不同的技术选型。
Spring boot/cloud下的使用方法:
1.增加配置redis和spring session的配置
spring.redis.host=127.0.0.1
spring.redis.password=123456
spring.redis.port=6379
spring.session.store-type=redis
2.创建配置类,开启注解
@Configuration
@EnableRedisHttpSession
public class UserCenterSessionConfig {
@Bean
public JedisConnectionFactory connectionFactory(){
return new JedisConnectionFactory();
}
}
Spring Cloud微服务项目中存在如下情况,导致session共享失效:
1.Zuul做API网关,转发时默认禁止传递Cookie。
需要开启Cookie
传递。
# zuul默认的zuul.sensitive-headers配置将过滤请求header的Cookie、Set-Cookie、
Authorization三个属性,导致cookie无法传播。
# 敏感头信息设置为空
zuul.sensitive-headers=
2.Feigin整合Hystrix,仿RPC调用其他微服务接口。
最终请求的
发送是由另一个Hystrix线程完成的,与Feign不在同一个线程,导致请求头信息丢失,Cookie传递失败。
需要做请求拦截,手
动添加。
@Configuration
public class FeignConfig {
@Bean
public RequestInterceptor requestInterceptor(){
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate requestTemplate) {
String sessionId =
RequestContextHolder.currentRequestAttributes().getSessionId();
requestTemplate.header("Cookie", "SESSION=" + sessionId);
}
};
}
}。