spring session和mongoDB实现分布式session共享

2018-01-08 13:34:01来源:网络收集作者:纳米程序员人点击

分享

阿里云爆款
spring session和mongoDB实现分布式session共享
研究背景

一方面是因为我们做token验证的时候是在zuul网关这边做的,用户认证通过后,需要对token的刷新来模拟session的功能,但遇到刷新后的值不能直接返回给浏览器的问题,一直没有找到很好的解决办法,第二方面就是大家对于session使用熟练,使用起来比token更加顺手。所以就研究了如何用spring session和MongoDB来实现分布式session的共享。


session和cookie简介

由于http协议是无状态的协议,为了能够记住请求的状态,于是引入了Session和Cookie的机制。我们应该有一个很明确的概念,那就是Session是存在于服务器端的,它是由tomcat管理的,存在于tomcat的内存中。而Cookie则是存在于客户端,更方便理解的说法,可以说存在于浏览器。http协议允许从服务器返回Response时携带一些Cookie,并且同一个域下对Cookie的数量有所限制,之前说过Session的持久化依赖于服务端的策略,而Cookie的持久化则是依赖于本地文件。有一类特殊的Cookie我们需要额外关注,那便是与Session相关的sessionId,他是真正维系客户端和服务端的桥梁。


分布式session简介

由于一般session只存在与单体应用中,当遇到分布式系统时,就会出现session不能共享的问题。这时就需要借助外部存储工具,将服务器上产生的session复制到该外部存储工具上面,以此实现不同服务器上共享同一个session,这就叫做分布式session。


下图是一般单体应用中session的工作原理图
spring session和mongoDB实现分布式session共享
下图是分布式session的工作原理图
spring session和mongoDB实现分布式session共享


分布式session的实现思路

核心思路:就是替换掉servlet容器创建和管理session的实现


实现方案:


1.利用Servlet容器提供的插件功能,自定义HttpSession的创建和管理策略,并通过配置的方式替换掉默认的策略。这方面其实早就有开源项目了,例如memcached-session-manager(目前我们的官方商城都是使用这个),以及tomcat-redis-session-manager。
不过这种方式有个缺点,就是需要耦合Tomcat/Jetty等Servlet容器的代码。


2.设计一个Filter,利用HttpServletRequestWrapper,实现自己的 getSession()方法,接管创建和管理Session数据的工作。spring-session就是通过这样的思路实现的。


3.与其自己写方法实现造轮子,不如直接使用轮子spring session。


spring session简介

spring-session是spring旗下的一个项目,把servlet容器实现的httpSession替换为spring-session,专注于解决 session管理问题。可简单快速且无缝的集成到我们的应用中。


特性


1.轻易把session存储到第三方存储容器,框架提供了redis、jvm的map、mongo、gemfire、hazelcast、jdbc等多种存储session的容器的方式。


2.同一个浏览器同一个网站,支持多个session问题。


3.Restful API,不依赖于cookie。可通过header来传递jessionID


4.WebSocket和spring-session结合,同步生命周期管理。


spring session原理

spring-session无缝替换应用服务器的request大概原理是:


1.自定义个Filter,实现doFilter方法


2.继承 HttpServletRequestWrapper 、HttpServletResponseWrapper 类,重写getSession等相关方法(在这些方法里调用相关的 session存储容器操作类)。


3.在 第一步的doFilter中,new 第二步 自定义的request和response的类。并把它们分别传递 到 过滤器链


4.把该filter配置到 过滤器链的第一个位置上


有兴趣研究源码的,可以看看这篇文章:
http://www.infoq.com/cn/articles/Next-Generation-Session-Management-with-Spring-Session


spring session和mongoDB整合使用

使用起来非常简单,只需四步,我们就能像以前一样使用session了。


第一步:新建一个spring boot项目。


第二步:添加依赖




org.springframework.boot
spring-boot-starter-data-mongodb



org.springframework.session
spring-session


org.springframework.boot
spring-boot-starter-web

第三步:在application.yml配置文件中添加配置


#mongoDB服务相关配置
spring:
data:
mongodb:
host: localhost
port: 27017
database: mydb

第四步:添加一个配置类


@Configuration
@EnableMongoHttpSession
public class HttpSessionConfig {
@Bean
public JdkMongoSessionConverter jdkMongoSessionConverter() {
return new JdkMongoSessionConverter();
}
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("JSESSIONID");
serializer.setCookiePath("/");
serializer.setDomainNamePattern("^.+?//.(//w+//.[a-z]+)$");
return serializer;
}
}

这样就能使用分布式session了,可以说灰常简单了!!!


参考文章
从零开始的Spring Session(二)
通过Spring Session实现新一代的Session管理

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台