zoukankan      html  css  js  c++  java
  • 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验证成功!

  • 相关阅读:
    记录k8s:k8s1.8.4无坑离线安装
    Aspose.Words 16.8 破解版、添加自定义HTML导出Jpeg压缩质量配置
    Mint linux 自定义上下文菜单实现ZIP压缩文件无乱码解压
    Mint Linux 安装 DotnetCore 遭遇无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系
    微信多开技巧
    Pycharm5注册方式
    控制Linux下 mono 服务的启动停止
    Cesium 源码笔记[2] CesiumWidget模块的实例化过程 ver1.67
    Cesium 源码打包入门 [ver1.69]
    Cesium 源码笔记[1] Viewer模块实例化的大致过程 ver1.67
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/jboss-eap-cluster-session-replication.html
Copyright © 2011-2022 走看看