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驗證成功!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM