设为首页 收藏本站
查看: 1020|回复: 0

[经验分享] memcached session

[复制链接]

尚未签到

发表于 2015-8-31 14:15:11 | 显示全部楼层 |阅读模式
一、需求背景
  一般的 servlet 容器(如 tomcat, resin 等)实现的 javax.servlet.http.HttpSession 的可见性都仅局限于一个 web 应用程序内,即使运行在同一个 JVM 里两个不同的 web 应用之间也不可共享 session 信息。通常情况下,我们可以考虑把会话状态信息保存在数据库中或者构建一个分布式 session 服务。 Memcached-session-0.9.jar (命名为 0.9 的原因是没有经过全面测试,但基本够用)是利用memcached 作为 session 服务器构建的一个分布式可共享 sesssion 解决方案。 Memcached-session 中的信息能够被多个共享顶级域名的 web 应用所共享(注:由于 memcached-session 的 sessionid 也是借助于 cookie 的,为防止 cookie 跨域的问题,必须要求各个 web 应用在相同的顶级域名下。 对于,要跨顶级域名的多个 web 应用程序共享 session 的问题,需要解决 cookie 跨域的问题,通常的做法是通过重定向的方式让 sessionid 在第三方的一个域上生成,详细情况可参考《 SSO(UserID 方式 )SP 与 SSO 之间的通信接口 V0.1.doc 》设计文档)。
二、使用步骤
  ( 1 )安装 memcached 服务端并启动在默认端口 11211 ,可以选择 windows 或 linux 版本
  
  注:所有的会话信息都以 SessionID 到 SessionObject (本身也是个类似 Map 的数据结构)键值对形式保存在 memcached 服务器端,各个 web 应用程序再通过 memcached 客户端来访问。这一点跟信息保存在数据库服务器上,各应用程序再通过 SQL 客户端来访问是一个道理。
  
  ( 2 )获取 memcached-session-0.9.jar 包,将该包及其依赖的 java_memcached_release_1.5.jar 和 commons-logging-1.0.4.jar 导入 WEB-INF/lib 目录下
  
  注: memcached-session-0.9.jar 依赖于 java_memcached_release_1.5.jar ( memcached 服务器的 java 客户端)和commons-logging-1.0.4.jar ( apache 的日志组件)
  
  ( 3 )编辑 memcached.properties 配置文件,以保证 memcached 客户端能够正确地访问 memcached 服务端。
  
  注: memcached-session-0.9.jar 是依据 classpath 去寻找 memcached.properties 配置文件的,所以必须保证memcached.properties 配置文件在 classpath 的根路径下,而且名称必须是 memcached.properties 。
  
  样例
  servers=127.0.0.1:11211,10.10.41.186:11211   (多个服务器之间用“ , ”隔开)
  init-connection = 10
  min-connection = 5
  max-connection = 20
  maint-sleep-millis = 30
  
  active-check = true
  failover = true
  nagle = false
  
  ( 4 )在 web.xml 中配置 MemcachedFilter ,以替换 sevlet 容器自有的 HttpSession 实现。
  
  <filter>
  <display-name>MemcachedFilter</display-name>
  <filter-name>MemcachedFilter</filter-name>
  <filter-class>com.umpay.session.MemcachedFilter <!-- [if !supportAnnotations]-->[lw1] <!-- [endif]-->  </filter-class>
  <init-param>
  <param-name>uuidCookieName <!-- [if !supportAnnotations]-->[lw2] <!-- [endif]-->  </param-name>
  <param-value>uuid</param-value>
  </init-param>
  <init-param>
  <param-name>uuidCookieDomain</param-name>
  <param-value></param-value>
  </init-param>
  <init-param>
  <param-name>uuidCookiePath</param-name>
  <param-value>/</param-value>
  </init-param>
  <init-param>
  <param-name>uuidCookieMaxAge <!-- [if !supportAnnotations]-->[lw3] <!-- [endif]-->  </param-name>
  <param-value>-1</param-value>
  </init-param>
  </filter>
  <filter-mapping>
  <filter-name>MemcachedFilter</filter-name>
  <url-pattern>/* <!-- [if !supportAnnotations]-->[lw4] <!-- [endif]-->  </url-pattern>
  </filter-mapping>
  
  ( 5 )透明地使用 MemcachedSession
  
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

       int c = 1;

       String count = (String)request.getSession() . <!-- [if !supportAnnotations]-->[lw5] <!-- [endif]-->  getAttribute( FLAG );

       if (count != null ) {

           c = Integer.parseInt (count)+1;

       }

       request.getSession().setAttribute( FLAG , c+ "" );

       request.getSession().setAttribute( "LastIP" , request.getRemoteAddr());

      

       PrintWriter writer = response.getWriter();

      

       request.getSession().setMaxInactiveInterval(8);

       writer.write( "MaxInactiveInterval = " + request.getSession().getMaxInactiveInterval()+ " second" );writer.println();

      

       writer.write( "you accessed this page at time " + c);writer.println();

       writer.write( "SESSIONID = " + request.getSession().getId());writer.println();

       writer.println();

      

       Enumeration<String> attrs = request.getSession().getAttributeNames();

       while (attrs.hasMoreElements()) {

           String key = attrs.nextElement();

           writer.write( "AttrEnum ->" +key+ "=" +request.getSession().getAttribute(key));

           writer.println();

       }

      

       writer.println();

       writer.write( "CreationTime = " + new Date(request.getSession().getCreationTime()));

       writer.println();

       writer.write( "LastAccessedTime = " + new Date(request.getSession().getLastAccessedTime()));

       writer.println();

      

  }
  
三、报文分析
  ( 1 )初次访问时
  请求报文:
  (Request-Line)       GET /MemSession/counter HTTP/1.1
  Host localhost:8080
  User-Agent     Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5
  Accept    text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  Accept-Language   zh-cn,zh;q=0.5
  Accept-Encoding    gzip,deflate
  Accept-Charset      gb2312,utf-8;q=0.7,*;q=0.7
  Keep-Alive      300
  Connection     keep-alive
  Cache-Control max-age=0
  
  响应报文:
  (Status-Line)   HTTP/1.1 200 OK
  Server     Apache-Coyote/1.1
  Set-Cookie    uuid=532b 3c 0b-c78e-4c2f-81fa-295ab9a57acf; Domain=""; Path=/ <!-- [if !supportAnnotations]-->[lw6] <!-- [endif]-->
  Set-Cookie      JSESSIONID=2560E054058B509381421BB017D 8A 418; Path=/MemSession <!-- [if !supportAnnotations]-->[lw7] <!-- [endif]-->
  Content-Length      272
  Date Fri, 19 Jun 2009 05:22:02 GMT
  (响应包体内容)
  MaxInactiveInterval = 8 second
  you accessed this page at time 1
  SESSIONID = 532b3c0b-c78e-4c2f-81fa-295ab9a57acf
  
  AttrEnum ->LastIP=127.0.0.1
  AttrEnum ->SessionCounter=1
  
  CreationTime = Fri Jun 19 13:22:11 CST 2009
  LastAccessedTime = Fri Jun 19 13:22:14 CST 2009
  
  ( 2 )再次访问时
  请求报文:
  (Request-Line)       GET /MemSession/counter HTTP/1.1
  Host localhost:8080
  User-Agent     Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5
  Accept    text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  Accept-Language   zh-cn,zh;q=0.5
  Accept-Encoding    gzip,deflate
  Accept-Charset      gb2312,utf-8;q=0.7,*;q=0.7
  Keep-Alive      300
  Connection     keep-alive
  Cookie    JSESSIONID=2560E054058B509381421BB017D8A418; uuid=532b 3c 0b-c78e-4c2f-81fa-295ab9a57acf <!-- [if !supportAnnotations]-->[lw8] <!-- [endif]-->
  Cache-Control max-age=0
  
  响应报文:
  (Status-Line)   HTTP/1.1 200 OK
  Server     Apache-Coyote/1.1
  Content-Length      272
  Date Fri, 19 Jun 2009 05:22:11 GMT
  (响应包体内容)
  MaxInactiveInterval = 8 second
  you accessed this page at time 2
  SESSIONID = 532b3c0b-c78e-4c2f-81fa-295ab9a57acf
  
  AttrEnum ->LastIP=127.0.0.1
  AttrEnum ->SessionCounter=2
  
  CreationTime = Fri Jun 19 13:22:11 CST 2009
  LastAccessedTime = Fri Jun 19 13:22:14 CST 2009
四、 FAQ
  ( 1 ) web 应用程序重启, MemcachedSession 信息会不会丢失呀?
  
  答:不会, MemcachedSession 信息是保存在 Memcached 服务端的,各个 web 应用只是通过 memcached-session-0.9.jar 去访问 Memcached 服务端。只有 Memcached 服务端重启时,信息才会丢失。
  
  ( 2 )服务端 MemcachedSession 的过期时间如何设置?
  
  答:在 web.xml 的 com.umpay.session.MemcachedFilter 的 initParam 初始化配置时通过
  <init-param>
  <param-name>uuidCookieMaxAge</param-name>
  <param-value>-1</param-value>
  </init-param>
  可以配置,该配置对所有客户端生效;
  也可以对某个浏览器专门使用 request.getSession().setMaxInactiveInterval(8); 来设置特定的超时时间。在实现机制上, memcached-session-0.9.jar 会在从 memcached 服务端取回数据时,依据系统当前时间 - 最后一次访问时间来判断 MemcachedSession 是否过期,如果过期,此时才删除服务端的数据。也就是说只有当数据已经过期,并且浏览器触发该数据的访问时 MemcachedSession 才会从服务端真的删除,否则只有让 memcached 自己删除。
  

<!-- [if !supportAnnotations]--><!-- [endif]-->
<!-- [if !supportAnnotations]-->
<!-- [endif]--><!-- [if !supportAnnotations]--> <!-- [endif]-->  <!-- [if !supportAnnotations]-->[lw1] <!-- [endif]--> Memcached-session-0.9.jar 中的组件,并在 init-param 中配置该组件的初始化参数
<!-- [if !supportAnnotations]--><!-- [endif]-->
<!-- [if !supportAnnotations]-->
<!-- [endif]--><!-- [if !supportAnnotations]--> <!-- [endif]-->  <!-- [if !supportAnnotations]-->[lw2] <!-- [endif]--> memcachedSession 的 sessionid 也是基于 cookie 的,且 sessionid 的生成规则是UUID 。
<!-- [if !supportAnnotations]--><!-- [endif]-->
<!-- [if !supportAnnotations]-->
<!-- [endif]--><!-- [if !supportAnnotations]--> <!-- [endif]-->  <!-- [if !supportAnnotations]-->[lw3] <!-- [endif]--> 指定服务端 sessionid 失效时间,其中 >0 表示在指定时间(秒)后失效; =0 表示永远不失效; <0 默认 30 分钟后失效。
<!-- [if !supportAnnotations]--><!-- [endif]-->
<!-- [if !supportAnnotations]-->
<!-- [endif]--><!-- [if !supportAnnotations]--> <!-- [endif]-->  <!-- [if !supportAnnotations]-->[lw4] <!-- [endif]--> 指定对哪些 url 请求的自有 HttpSession 被 MemcachedSession 替换掉。
<!-- [if !supportAnnotations]--><!-- [endif]-->
<!-- [if !supportAnnotations]-->
<!-- [endif]--><!-- [if !supportAnnotations]--> <!-- [endif]-->  <!-- [if !supportAnnotations]-->[lw5] <!-- [endif]--> 获取的 Session 实现实例实际是 com.umpay.session.MemcachedSession ,采用的是装饰器模式给偷梁换柱了。
<!-- [if !supportAnnotations]--><!-- [endif]-->
<!-- [if !supportAnnotations]-->
<!-- [endif]--><!-- [if !supportAnnotations]--> <!-- [endif]-->  <!-- [if !supportAnnotations]-->[lw6] <!-- [endif]--> 用户自己定义的 MemcachedSession 对应的 uuid
<!-- [if !supportAnnotations]--><!-- [endif]-->
<!-- [if !supportAnnotations]-->
<!-- [endif]--><!-- [if !supportAnnotations]--> <!-- [endif]-->  <!-- [if !supportAnnotations]-->[lw7] <!-- [endif]--> Servlet 容器自有的 SessionID
<!-- [if !supportAnnotations]--><!-- [endif]-->
<!-- [if !supportAnnotations]-->
<!-- [endif]--><!-- [if !supportAnnotations]--> <!-- [endif]-->  <!-- [if !supportAnnotations]-->[lw8] <!-- [endif]--> 浏览器在再次访问同一域下的 URL 时,主动把先前下发的 uuid 的 cookie 信息包裹在请求报文中,以便服务端依据该 ID 匹配 MemcachedSession 对象。
<!-- [if !supportAnnotations]--><!-- [endif]-->

  • MemSession.rar (419.1 KB)
  • 下载次数: 55


  • SSO_UserID方式_SP与SSO之间的通信接口V0.1.pdf (188.3 KB)
  • 下载次数: 31


  • memcached-session使用说明V0.1.pdf (304.2 KB)
  • 下载次数: 47


  • memcached全面剖析.pdf (929.5 KB)
  • 下载次数: 49

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-106867-1-1.html 上篇帖子: IBatis.Net使用MemCached替换内置缓存策略 下篇帖子: Memcached 服务器端命令
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表