您的位置:首页 > 其它

使用apahce 的mod_proxy 实现jboss负载均衡

2013-12-10 23:47 288 查看
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">







另一台jboss实例 修改成node1然后编辑

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

添加如下

....

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

</web-app>




接着在

/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>

在node1和node2上先后启动服务

/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




最后启动apache服务。

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

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

对用户是透明的。


浏览器访问,并提交内容




10.0.2.202 的jboss实例输出的内容




从访问的监控来看,在客户端提交内容后,提交的所有内容(包括之前提交的内容)都会复制到另一台jboss实例,jboss默认使用UDP广播方式进行session复制,这样来看,导致了不必要的冗余数据的session复制,占用了一定的网络带宽。(不知有什么好的办法,让每次只更新新提交的内容,这样也可以节约带宽,后续完善。)还有当一台jboss实例停掉后,客户端访问时才检查到jboss不工作了。当其中一台主机的jboss实例停掉后,另一台正常的jboss实例能够检测到,并打印出信息



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



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

注意:貌似mod_proxy 不可以将session的sticky和共享一起配置,但apache的mod_jk和nginx可以集成配置。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息