专栏首页菩提树下的杨过jboss eap 6.3 集群(cluster)-Session 复制(Replication)

jboss eap 6.3 集群(cluster)-Session 复制(Replication)

本文算是前一篇的后续,java web application中,难免会用到session,集群环境中apache会将http请求智能转发到其中某台jboss server。假设有二个jboss server:Server A,Server B,Session值在Server A上。用户在访问某一个依赖session的页面时,如果第一次访问到Server A,能正常取到Session值,刷新一下,如果这时转发到Server B,Session值取不到,问题就来了。

解决的办法简单到让人不敢相信,在app的web.xml中加一行 <distributable /> 即可(前提:jboss cluster是使用mod_cluster实现的),有了这个节点后,向某台server写入session时,session会自动复制到其它server node。

下面来具体验证一下:

网络环境:

如上图,有二台机器:172.21.129.181(Master Server & Apacha Server)、172.21.129.128(Slave Server)

User所在的计算机IP为: 172.21.129.57 (图中未标出)

Sample Application:

为了验证,我们建一个最简单的spring mvc web应用

Controller代码如下:

 1 package com.cnblogs.yjmyzz;
 2 
 3 import javax.servlet.http.HttpServletRequest;
 4 import javax.servlet.http.HttpSession;
 5 
 6 import org.apache.log4j.Logger;
 7 import org.springframework.stereotype.Controller;
 8 import org.springframework.ui.Model;
 9 import org.springframework.web.bind.annotation.RequestMapping;
10 import org.springframework.web.bind.annotation.RequestMethod;
11 import org.springframework.web.servlet.ModelAndView;
12 
13 @Controller
14 public class HomeController {
15 
16     Logger log = Logger.getLogger(this.getClass());
17 
18     private static final String sessionKey = "test";
19 
20     /**
21      * 写入session
22      * @param request
23      * @return
24      */
25     @RequestMapping(value = "/session-write", method = RequestMethod.GET)
26     public String writeSession(HttpServletRequest request) {
27         HttpSession session = request.getSession();
28         session.setAttribute(sessionKey, "sample value");
29         return "session/write";
30     }
31 
32     /**
33      * 读取session
34      * @param request
35      * @return
36      */
37     @RequestMapping(value = "/session-read", method = RequestMethod.GET)
38     public ModelAndView readSession(HttpServletRequest request) {
39         HttpSession session = request.getSession();
40         Object sessionValue = session.getAttribute(sessionKey);
41         ModelAndView model = new ModelAndView();
42         if (sessionValue != null) {
43             model.addObject(sessionKey, sessionValue);
44         }
45         
46         try {
47             //显示几个IP到页面,用于辅助判断本次Http请求转发到了哪台server
48             String hostInfo = "InetAddress.getLocalHost() = "
49                     + java.net.InetAddress.getLocalHost()
50                     + "<br/>request.getRemoteAddr() = "
51                     + request.getRemoteAddr() + ":" + request.getRemotePort()
52                     + "<br/>x-forwarded-for = " + getUserReadIP(request)
53                     + "<br/>request.getLocalAddr() = " + request.getLocalAddr()
54                     + ":" + request.getLocalPort();
55             model.addObject("host", hostInfo);
56 
57         } catch (Exception e) {
58 
59         }
60         model.setViewName("session/read");
61         return model;
62     }
63 
64     // 获取用户真实IP
65     private String getUserReadIP(HttpServletRequest request) {
66         if (request.getHeader("x-forwarded-for") == null) {
67             return request.getRemoteAddr();
68         }
69         return request.getHeader("x-forwarded-for");
70     }
71 
72 }

write.jsp:(写入session)

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <html>
 4 <head>
 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 6 <title>session write test</title>
 7 </head>
 8 <body>
 9     <h1>Session写入成功!</h1>
10 </body>
11 </html>

read.jsp:(显示session)

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <html>
 4 <head>
 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 6 <title>session read test</title>
 7 </head>
 8 <body>
 9     <h1>Session("test"):${test}</h1>
10     <h1>${host}</h1>
11 </body>
12 </html>

准备就绪,依次以domain模式启动master server、slave server上的jboss,最后启动apache server。

然后访问:

http://172.21.129.181/ModClusterSample/session-write.do 写入session

继续访问:

http://172.21.129.181/ModClusterSample/session-read.do 读取session

从输出的几个IP看,本次请求apache转发到了 172.21.129.128上(即:slave Server),user客户端的IP为 172.21.129.57,而apache server的IP为172.21.129.181

另外第一行表明正确读取到了session值:sample value

这时进入master server的jboss控制台,将slave master上的jboss server给stop掉

再次刷新user机器上的http://172.21.129.181/ModClusterSample/session-read.do

可以看到,因为slave server上的jboss server已经被停掉了,所以本次http请求被转发到了172.21.129.181上(即master server),但是session值仍然能正常输出,说明session值在写入的同时,确实已经被复制到二台jboss server上了,session replication验证成功!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • silverlight 4 tools for vs2010无法在vs2010 SP1上安装的解决办法

    环境:英文版vs2010 sp1 + vs2013 RC 90天体验版 原来可以正常做silverilght 4 项目开发,今天因为vs2013 RC过了90天...

    菩提树下的杨过
  • Oracle XE http端口8080的修改

    Oracle Express Edition(XE)默认的http端口是8080,这跟JBoss/Tomcat的默认端口相同,导致Jboss启动冲突。 修改办法...

    菩提树下的杨过
  • Flash/Flex学习笔记(9):ActionScript3.0与Javascript的相互调用

    原理跟Silverlight中的几乎如出一辙(见Silverlight如何与JS相互调用): ActionScript3代码: btnCallJs.addEve...

    菩提树下的杨过
  • Tomcat Session管理分析【面试+工作】

    上文中在Tomcat的context.xml中配置了Session管理器RedisSessionManager,实现了通过redis来存储session的功能;...

    Java帮帮
  • 程序员过关斩将--解决分布式session问题

    说到 session,我相信每个程序员都不陌生,或多或少在项目中使用过。session 这个词,其实是一个抽象的概念,它不像 Cookie 那样有着明确的定义。...

    架构师修行之路
  • php面试笔记(8)-php基础知识-会话控制考点

    在上一篇中,冷月为大家分享了文件及目录处理考点,大家一定要根据自己的薄弱点进行查漏补缺,尝试着练习目录的复制和删除函数的编写。今天,冷月为大家分享会话控制考点。

    学长冷月
  • [PHP] session_write_close()的作用

    简单地说,当开启session_start以后,这个session会一直开启,并且被一个用户使用。其他用户开启session的话要等待第一个session用户关...

    陶士涵
  • PHP设置Redis储存Session

    我们在之前的文章已经讲到了session是将数据储存在本地文件中,并且将session_id返回给客户端(浏览器会储存在cookies里)。

    仙士可
  • php session_decode函数用法讲解

    session_decode() 对 data 参数中的已经序列化的会话数据进行解码, 并且使用解码后的数据填充 _SESSION 超级全局变量。

    砸漏
  • PHP设置Redis储存Session,自定义session驱动

    我们在之前的文章已经讲到了session是将数据储存在本地文件中,并且将session_id返回给客户端(浏览器会储存在cookies里)。

    宣言言言

扫码关注云+社区

领取腾讯云代金券