session 机制是一种服务器端的机制,服务器使用一种散列表或者类似的结构来保存信息。在使用分布式 session 前会有这样两个疑问: 1)为什么采用分布式 session : 当我们的系统当中有多台服务器的时候,我们无法保证 session 在多台机器都存在,这是因为我们用户的请求不一定会被路由到同一台机器上。也就是说对应一个用户的 session 信息在服务器 A 上存在,但是在服务器 B 上不存在,因为请求被路由到了服务器 A 上,所以我们需要让集群中的多台机器共享 session信息。 2)为什么重写 session: session 只能存储在本地 web服务器的内存当中,但无法满足 session 在多台服务器的分布式环境下,多台机器共享 session 数据的问题,所以我们需要重写,让它在分布式环境下,拥有 session 数据共享功能。 session配置方法 当程序需要为某个客户端的请求创建一个 session 的时候,服务器首先检查这个客户端的请求里是否包含了一个 session 标识,称为 session-id。 如果已经包含一个 session-id 则说明以前已经为此客户创建过 session,服务器就按照session-id 把这个 session 检索出来使用(如果检索不到,可能会新建一个,这种情况可能出现在服务端已经删除了该用户对应的 session 对象,但用户人为地在请求的 URL 后面附加上一个 JSESSION 的参数)。 如果客户请求不包含 session-id,则为此客户创建一个 session 并且生成一个与此 session 相关联的 session-id,这个session-id将在本次响应中返回给客户端保存。 其实分布式 session 并不是一个特别难的课题,实现的思路也有很多种。今天我将介绍一种使用起来非常简单的方法,只要做如下配置即可使用: 1 )导入一个 jar 在 pom 文件中 2) 在 web.xml 文件中配置一个 filter session 使用方法 分布式 session 的使用:从使用者的角度不需要知道是否为分布式 session,一句即可搞定,而且和容器无关。 为了保证读者可以理解这种方法,直播,下面我将以最简洁的方法来实现。 1、 拦截器的实现 这个拦截器拦截了所有路径的客户端请求,并且在请求进去 Controller 之前把HttpServletRequest 替换成我自己实现的一个 HttpServletRequest,叫做DistributionSessionRequestWrapper 2、 DistributionSessionRequestWrapper 的实现
HttpServletRequestWrapper 是 HttpServletRequest 的装饰类,通过继承它,覆盖你希望改变的方法,你可以改变当前 HttpServletRequest 对象的状态。 从 session 的使用角度上来说,你只会用 getSession() 这个方法,那么我覆盖这个方法就ok了,在 getSession() 中我做了两件事: new 了一个的 HttpSession 实现叫做 DistributionSessionImpl 在 cookie 当中写入一个叫 pcxSessionId 的 cookie 进去,实际上就和 tomcat 的 jessionid 一样,这个就是用来从分布式缓存中寻找对应 session 数据的 key。 3、 DistributionSessionImpl 的实现
在 DistributionSessionImpl 中有两个属性比较重要 sessionMap:用来存储一次请求中的 session 数据 sessionStore:把用户的 session 数据存储到分布式缓存的类 getId() 方法:通过这个方法可以获取用户的 cookie 中 key=“pcxSessionId”的value 值 getAttribute():通过key中 pcxSessionId从缓存中获取用户的 session 数据 setAttribute():如果为空的话,那么从分布式缓存中获取用户的 session 数据,当然如果这个用户是第一次访问的话,这个 sessionMap 可能还是为空,这个逻辑的话在sessionStore 有判断;把key-value数据存储到本地的sessionMap中,然后把数据推送到分布式缓存中 removeAttribute():清除本地 map 中的 Attribute 然后再把分布式缓存中的getID() 给删掉 Invalidate():先清除本地的 sessionmap 然后删除分布式缓存中的 session 数据,最后清除 cookie 4、 SessionStore 的实现 (责任编辑:本港台直播) |