jboss集群session复制原理:

jboss session复制是jboss session同步的一种实现。原理是在各Jboss节点间建立横向联系,每个节点都将本节点的session变化同步到其他所有节点上。

jboss的session复制与HTTP集群是相互配合、相互独立的两个系统。session复制是节点间的横向联系,HTTP集群是负载均衡器与节点的纵向联系。

   10.0.2.203 – 安装JDK 1.6,JBoss 7,JBoss节点名称为jboss1

   10.0.2.202 – 安装JDK 1.6,JBoss 7,JBoss节点名称为jboss2

   10.0.2.200 – 安装Apache httpd,mod_proxy   #mod_proxy默认系统就提供


安装jdk和jboss 此处就不多说了,因为jboss默认只监听127.0.0.1,所以需要修改

/usr/local/jboss-4.2.2.GA/server/default/deploy/jboss-web.deployer 目录下的

server.xml文件,

<Connector port="8080" address="0.0.0.0"    #8080是监听端口,后面是监听IP(IP需要修改)

下面是apache 的配置:

<IfModule mod_proxy.c>

ProxyRequests Off

ProxyPass /mycluster !

#

<Proxy balancer://mycluster>

       BalancerMember http://10.0.2.203:8080 route=node1 loadfactor=1

       BalancerMember http://10.0.2.202:8080 route=node2 loadfactor=1

       ProxySet lbmethod=bytraffic

#       ProxySet stickysession=ROUTEID

#    Order deny,allow

#    Deny from all

#    Allow from 10.0.2.0

</Proxy>

ProxyTimeout 600

ProxyPass /  balancer://mycluster

Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e;paht=/" env=BALANCER_ROUTE_CHANGED


<Location /mycluster>

       SetHandler balancer-manager

       Order Deny,Allow

       Deny from all

       Allow from all

</Location>

注意:测试时注意iptables和selinux对实验的影响,当开启selinux时,客户端不能访问,报503错误,查看日志提示permission deny,执行 setenforce 0 就可以访问。这个503错误 也可能是jbos未启动导致的。


此时启动两台主机的jboss服务,然后再重启apache服务,打开浏览器访问 http://10.0.2.200/mycluster 监控页面,可以看到访问统计情况,接着访问 http://10.0.2.203 (最好将两台主机的jboss默认页面修改,添加各自的IP,方便查看)

此时实现了session的sticky。


下面是session 共享的配置:

从上面的实验来看,只做到了负载均衡,但有个问题,客户端连接到服务端,正在提交内容时,一台jboss实例不幸停机了,后面提交的内容会转发到正常的jboss实例,但是之前提交的内容不会复制正常的jboss实例,此时需要配置session的复制,也就是session的共享。


/usr/local/jboss/server/default/deploy/jboss-web.deployer/server.xml 文件,


<Engine name="jboss.web" defaultHost="10.0.2.203" > 修改成<Engine name="jboss.web" defaultHost="10.0.2.202" jvmRoute="node2">


104351515.jpg

133353762.jpg

另一台jboss实例 修改成node1

然后编辑


/usr/local/jboss/server/all/deploy/jboss-web.deployer/ROOT.war/WEB-INF/web.xml 文件


添加如下


....


<distributable/>                   #如果没有添加,则不会session复制


</web-app>


104525612.jpg

接着在


/usr/local/jboss/server/all/deploy/jboss-web.deployer/ROOT.war/ 目录下 创建index.jsp 测试文件

内容为:


<%@ page contentType="text/html; charset=GBK" %>


<%@ page import="java.util.*" %>


<html><head><title>Cluster App Test</title></head>


<body>


Server Info:


<%


out.println(request.getLocalAddr()+":"+ request.getLocalPort()+"<br>");%>


<%


out.println("<br> ID " + session.getId()+"<br>");


String dataName = request.getParameter("dataName");


if (dataName != null && dataName.length() > 0) {


String dataValue = request.getParameter("dataValue");


session.setAttribute(dataName, dataValue);


}


out.print("<b>Session list</b>");


Enumeration e = session.getAttributeNames();


while (e.hasMoreElements()) {


String name = (String)e.nextElement();


String value = session.getAttribute(name).toString();


out.println( name + " = " + value+"<br>");


System.out.println( name + " = " + value);


}


%>


<form action="index.jsp" method="POST">


id:<input type=text size=20 name="dataName">


<br>


key:<input type=text size=20 name="dataValue">


<br>


<input type=submit>


</form>


</body>


</html>


node1node2上先后启动服务


/usr/local/jboss/bin/run.sh -c all -Djboss.bind.address=10.0.2.202


/usr/local/jboss/bin/run.sh -c all -Djboss.bind.address=10.0.2.203


104649158.jpg

最后启动apache服务。


访问:http://station1/index.jsp,输入值并提交,查看日志,关闭正在处理session


话的jboss,再次提交页面,如能看到session会话被复制到另一台jboss上表示成功,此动作


对用户是透明的。

104756839.jpg

浏览器访问,并提交内容


104840329.jpg

10.0.2.202 jboss实例输出的内容


104922427.jpg

从访问的监控来看,在客户端提交内容后,提交的所有内容(包括之前提交的内容)都会复制到另一台jboss实例,jboss默认使用UDP广播方式进行session复制,这样来看,导致了不必要的冗余数据的session复制,占用了一定的网络带宽。(不知有什么好的办法,让每次只更新新提交的内容,这样也可以节约带宽,后续完善。)

还有当一台jboss实例停掉后,客户端访问时才检查到jboss不工作了。

当其中一台主机的jboss实例停掉后,另一台正常的jboss实例能够检测到,并打印出信息

115235295.jpg

当停掉的jboss实例又恢复后,另一台正常的jboss可以检测到:并打印出信息

095418608.jpg

当客户端请求到来后,apache不会转发到恢复的jboss实例,还是由当前的jboss实例来处理。


注意:貌似mod_proxy 不可以将session的sticky和共享一起配置,但apache的mod_jk和nginx可以集成配置。