为了账号安全,请及时绑定邮箱和手机立即绑定

jboss eap 6.3 集群(cluster)

标签:
安全

本文算是前一篇的后续,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验证成功!

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消