当服务器的访问压力达到一定程度时,会采用分布式部署方案,即分布式集群部署,多个服务节点都可以提供同样的服务能力,这样,当大量的http请求到达服务端时,由负载均衡算法,将不同的请求相对均匀地分发到不同的服务节点上,达到了降低单个服务节点的访问压力,同时也可以解决服务单点故障问题。


采用分布式集群部署方案,一般都要解决session共享问题,如下图所示:

分布式Session一致性问题 session分布式方案_session

考虑问题:同一个client依次发送3个http请求,顺序依次是request1,request2,request3,经负载均衡算法,被分发到3个不同的服务节点node1,node2,node3,那么,client首先访问server node1进行登录操作,登录成功后创建session,server node1上保存session,同时执行response.addCookie(sessionId)返回给client,client保存cookie;然后client发起请求request2,此时request2访问到server node2,在server node2上根据sessionId找不到session,会提示session不存在,即server node1和 server node2无法共享同一个session...


那么如何让不同的server node共享session呢?

如下图所示:


分布式Session一致性问题 session分布式方案_session_02


设计需要思想:需要一个分布式cache(redis、memcached等),然后server node在创建session时,将session存入到分布式cache中,获取session时,从分布式session中取,这样就实现session共享了...


设计思想了解后,那么接下来就是实现方案了...


如下图所示:

分布式Session一致性问题 session分布式方案_分布式Session一致性问题_03

我们只要做一件事,就是将session相关的操作访问我们自定义的方法,我们自定义的方法操作的是分布式cache,那么就可以解决session共享问题了,也就是下图所示:

分布式Session一致性问题 session分布式方案_分布式Session一致性问题_04

首先,我们自定义HttpServletRequestWrapperConcrete、HttpSessionWrapper两个类,分别继承HttpServletRequestWrapper、HttpSession,然后对getSession(...)、getAttribute(name)、setAttribute(name,value)这些常用的方法进行override(重写),这样,原本访问HttpServletRequestWrapper、HttpSession的方法就可以访问我们自定义的HttpServletRequestWrapperConcrete、HttpSessionWrapper中相应的方法了,因此,开发人员就可以使用之前的调用方式一样进行操作了...


接下来就是访问的问题了,看下图:

分布式Session一致性问题 session分布式方案_session_05

如何将HttpServletRequest对象变成我们自定义的HttpServletRequestWrapperConcrete对象呢?以及将HttpSession对象变成HttpSessionWrapper对象呢?


对于1,将HttpServletRequest变成HttpServletRequestWrapperConcrete的问题,可以用Filter来实现:

分布式Session一致性问题 session分布式方案_redis_06

对于2,将HttpSession变成HttpSessionWrapper的问题,实现方式是将HttpSession作为HttpServletRequestWrapperConcrete的成员变量,然后当HttpServletRequestWrapperConcrete的对象request创建session的时候,将执行request.session = new HttpSessionWrapper(...),这样访问的问题就解决了...


下面,给出实现流程...

分布式Session一致性问题 session分布式方案_分布式_07

分布式Session一致性问题 session分布式方案_缓存_08

分布式Session一致性问题 session分布式方案_分布式Session一致性问题_09

分布式Session一致性问题 session分布式方案_分布式_10


至此,整个分布式session的实现方案结束...