分布式Session原理,最简单而高效的实现方式

问题1,你要理解JSESSIONID与cookie是什么关系,session与cookie到底有什么关系。

简单来说,当第一次request server时,server产生JSESSIONID对应的值1,通过http header set-cookie,传递给browser,browser检测到http response header 里带set-cookie,那么browser就会create一个cookie,key=JSESSIONID,value=值1,而后的每次请求,browser都会把cookie里的键值对,放到http request header里,传递给server。

当在server端调用http.getSession()方法时,server会先从http request header里解析出来JSESSIONID的值,再从一个Map容器里去找有没有value,如果没有,就会产生一个HttpSessioon对象,放到这个Map容器里,同时设置一个最大生存时间。HttpSession你也可以把它想象成是一个Map,可以getAttribute(),可以setAttribute()。

cookie和session就这么简单。

好,现在我们说说分布式Session如何实现。


最前端的负载均衡器,如nginx,会把request原封不动的平均分配到集群中的一台机器,所喂原封不动,就是指的request header里的内容不变。


我们先来看看tomcat是怎么处理单机的session的。

分布式Session原理,最简单而高效的实现方式_第1张图片


分布式Session原理,最简单而高效的实现方式_第2张图片


分布式Session原理,最简单而高效的实现方式_第3张图片


问题2,具体实现分布式Session

好,看明白了吧,其实要实现分布式Session,只要得到JSESSIONID的值就可以了,剩下的操作无非就是根据key去redis或memcache中存取值,并缓存到本机内存中。

String requestedSessionId = req.getRequestedSessionId();//这就代表某一位用户了,至于有没有登录,那就看DSession属性里是否有登录后的信息即可。
//TODO, DSession dSession= DistributeSessionManager.getDistributeSession(requestedSessionId);

//TODO, DSession是一个接口,至少要提供以下相类似的方法

分布式Session原理,最简单而高效的实现方式_第4张图片


问题3,在集群中的某一台机器上,如何高效的判断Session过期

tomcat源码是得到一个sessionList,然后遍历,这种做法是相当低效的,源码分析请参考 http://www.tuicool.com/articles/6fMZvq

有个叫 Timing Wheel(时间轮)的东西,这个东西很棒,可以高效的管理超大量的定时任务,也是能想到的最高效最好的设计方案,而且,Timing Wheel的java实现也简单。

问题4,分布式session,如何处理logou

loginIn还好说,直接根据sessionid从cache中拿数据即可。但是怎么处理logou呢,logout时,要清理local cache中与session相关的信息。

由于logout对时时性要求几乎没有,晚个几少钟几十秒钟,都无所谓的,所以可以利用消息中间件来处理,比如ActiveMQ等。

问题5,最好的分布式session处理方法是什么

最好的处理方法就是让前端的LoadBalance,根据sessionId,把请求进行hash或一致性hash,让用户固定到集群中的某台机器上,这样做最大的好处是,可以充分利用内存,相当于单机处理逻辑了。

所以呢,分布式Session处理方案就被简化了太多太多了,与单机处理逻辑没有任何差别。

你可能感兴趣的:(Java,web)