一.基础知识
1.1高可用方案的2个基本问题
(1) Load Balance
需要注意负载均衡问题, 使得请求可以较好分配。
它有2种表现形式
(a) 访问地址不同
例如, 网站www.hello.com. 当访问www.hello.com/us, 由Node1做出响应. 当访问www.hello.com/cn, 由Node2做出相应
(b) 任务分发
例如, 网站www.hello.com. 当有50000个request到达时候, 将这些request按照2:1的比例分发给Node1和Node2
(2) High Availability
需要注意Session状态转移问题, 即在某个Server Node发生故障时保持Session连接。例如,当Apache将某个request分发给Node1后, 并且进行了某些操作,这时候Node1突然crash或者Node1出现了网络故障, 这时要保证Session不会丢失, Session ID唯一和保留在Session中的内容不会丢失。
1.2基本原理介绍
<!--[if !vml]--><!--[endif]-->
<!--[if !vml]-->如图1 所示,Node 1和Node 2所是Apache的两个worker。当有request到达时, 由Apache通过Ajp13 协议动态的将请求分发给Node 1和Node 2。 例如, 当发送的request送给Node 1时,由Node 1处理发送来的request, 进行处理后将response按照原路径返回,交给Apache。此后Apache再将收到的response返回给client端。
两个worker,Node 1和Node 2是真正负责处理client端发送来的请求。为了保持Session的一致性和稳定性,两个Node需要进行同步,即Session的复制,才能保证数据的统一。
二、举例说明配置
2.1环境说明
【机器A】
操作系统: Window Home Edition
IP地址: 192.168.0.42
JBoss 服务器: Apache, 2.2.4
JBoss 4.2 (Node 1)
JDK版本: 1.5.0
【机器B】
操作系统: FreeBSD
IP: 192.168.0.180
Server: JBoss 4.2 (Node 2)
JDK: 1.5.0
2.2配置流程
<!--[if !supportLists]-->(1) <!--[endif]-->%Apache_HOME%目录下
<!--[if !supportLists]-->(a) <!--[endif]-->到www.apache.com下载mod_jk.so到modules目录
<!--[if !supportLists]-->(b) <!--[endif]-->在conf目录下的httpd.conf文件最后写入
# Include mod_jk's specific configuration file
Include conf/mod-jk.conf
<!--[if !supportLists]-->(c) <!--[endif]-->在conf目录下创建mod-jk.conf文件、uriworkermap.properties文件、workers.properties文件,文件的内容见附录一。其目的是为Apache设置2个worker为其服务。
<!--[if !supportLists]-->(2) <!--[endif]-->Node1%JBOSS_HOME%\server\all目录下
<!--[if !supportLists]-->(a) <!--[endif]-->修改访问地址, 使得外部可以以主机IP地址进行访问
在deploy\jboss-web.deployer目录下的server.xml
<Connector port="8080" address= {jboss.bind.address}…>改为<Connector port="8080" address="0.0.0.0"…>;
<Connector port="8009" address= {jboss.bind.address}…>改为<Connector port="8009" address="0.0.0.0"…>。
<!--[if !supportLists]-->(b) <!--[endif]-->使得JBoss知道自己为Node1结点
在deploy\jboss-web.deployer目录下的server.xml
<Engine name="jboss.web" defaultHost = "localhost">
改为
<Engine name="jboss.web" defaultHost= "localhost" jvmRoute="node1">。
<!--[if !supportLists]-->(c) <!--[endif]-->通知Node 1添加一个jvmRoute值到会话cookies中,以便mod_jk可以路由随后的请求
在deploy\jboss-web.deployer\META-INF目录下的jboss-service.xml
<attribute name="UseJK">false</attribute>改为
<attribute name="UseJK">true</attribute>。
<!--[if !supportLists]-->(d) <!--[endif]-->定义重定向地址
在deploy\jboss-web-cluster.sar\META-INF目录下的jboss-service.xml
<TCP bind_addr = "thishost" start_port = "7810" loopback= "true"…>
改为
<TCP bind_addr = "192.168.0.42" start_port= "7810" loopback="true"…>;
<TCPPING initial_hosts= "thishost[7810], otherhost[7810]" port_range="3"…>
改为
<TCPPING initial_hosts= "192.168.0.42[7810], 192.168.0.180[7810]" port_range="3"…>。
<!--[if !supportLists]-->(3) <!--[endif]-->Node2%JBOSS_HOME%\server\all目录下
<!--[if !supportLists]-->(a) <!--[endif]-->修改访问地址, 使得外部可以以主机IP地址进行访问
在deploy\jboss-web.deployer目录下的server.xml
<Connector port="8080" address= {jboss.bind.address}…>改为<Connector port="8080" address="0.0.0.0"…>;
<Connector port="8009" address= {jboss.bind.address}…>改为<Connector port="8009" address="0.0.0.0"…>。
<!--[if !supportLists]-->(b) <!--[endif]-->使得JBoss知道自己为Node2结点
在deploy\jboss-web.deployer目录下的server.xml
<Engine name="jboss.web" defaultHost = "localhost">
改为
<Engine name="jboss.web" defaultHost= "localhost" jvmRoute="node2">。
<!--[if !supportLists]-->(c) <!--[endif]-->通知Node 2添加一个jvmRoute值到会话cookies中,以便mod_jk可以路由随后的请求
在deploy\jboss-web.deployer\META-INF目录下的jboss-service.xml
<attribute name="UseJK">false</attribute>改为
<attribute name="UseJK">true</attribute>。
<!--[if !supportLists]-->(d) <!--[endif]-->定义重定向地址
在deploy\jboss-web-cluster.sar\META-INF目录下的jboss-service.xml
<TCP bind_addr = "thishost" start_port = "7810" loopback= "true"…>
改为
<TCP bind_addr = "192.168.0.180" start_port= "7810" loopback="true"…>;
<TCPPING initial_hosts= "thishost[7810], otherhost[7810]" port_range="3"…>
改为
<TCPPING initial_hosts= "192.168.0.180[7810], 192.168.0.42[7810]" port_range="3"…>。
<!--[if !supportLists]-->(4) <!--[endif]-->在自己的应用程序中
<!--[if !supportLists]-->(a) <!--[endif]-->设置使得自己的应用程序使用集群
在WEB-INF目录下的web.xml文件中<web-app>下添加
<distributable/>
<!--[if !supportLists]-->(b) <!--[endif]-->在设置Jboss配置信息
在WEB-INF目录下创建jboss-web.xml文件,文件内容见附录二
三、实验方案
【实验一】验证负载分配
实验步骤:
<!--[if !supportLists]-->(1) <!--[endif]-->在浏览器中输入http://l92.168.0.42/jmx-console/
<!--[if !supportLists]-->(2) <!--[endif]-->另开一个浏览器窗口, 输入http://l92.168.0.42/jmx-console/,可能会出现另外一个node的jmx-console
【实验二】验证负载分配和Session ID保持
实验步骤:
<!--[if !supportLists]-->(1) <!--[endif]-->创建文件test.jsp, 在test.jsp中打印node的IP地址, session id和singleton实例的某一自增变量
<!--[if !supportLists]-->(2) <!--[endif]-->在一个浏览器窗口中访问test.jsp, 显示单一node的IP地址, session id和singleton实例的某一自增变量, 点击刷新按钮, 看见同一IP地址和Session id
<!--[if !supportLists]-->(3) <!--[endif]-->另开一个浏览器窗口访问test.jsp, 可能会显示另一node的IP地址, session id和singleton实例的某一自增变量, 点击刷新按钮, 看见一IP地址和Session id. 在这里每个singleton变量的自增值是分别增加的.
<!--[if !supportLists]-->(4) <!--[endif]-->仅保留一个浏览器窗口, 若ip显示42机器, 则把42机器上的jboss停止掉. 否则把180上的jboss停止掉. 刷新浏览器窗口. 可以看见ip值发生变化, 但session id保持不变
【实验三】验证Session内容
<!--[if !supportLists]-->(1) <!--[endif]-->创建文件first.jsp, 在first.jsp中输入一个值, 将其存入session中, 以post方法在second.jsp中显示session中存在的值和打印值到控制台.
<!--[if !supportLists]-->(2) <!--[endif]-->刷新second.jsp, 显示session中存在的值
<!--[if !supportLists]-->(3) <!--[endif]-->停止掉刚刚在控制台打印信息的node结点server
<!--[if !supportLists]-->(4) <!--[endif]-->刷新second.jsp, 显示session中存在的值
【实验四】数据统计, 查看性能
在%APACHE_HOME%\bin目录有应用程序ab, 利用ab做数据统计
分别向服务器发送500个请求,每次发送20个,查看最终的数据统计结果
ab -n 500 -c 20 http://192.168.0.42:8080/web-console/
ab -n 500 -c 20 http://192.168.0.180:8080/web-console/
ab -n 500 -c 20 http:// 192.168.0.42/web-console/
四、注意事项
8080端口问题
有时可能出现JBOSS端口冲突问题, 可以将%JBOSS_HOME%\all\deploy\jboss-web.deployer\Server.xml中定义的默认端口8080改为其他不用端口
ALL 模式运行问题
JBOSS以ALL模式在windows运行的命令为%JBOSS_HOME%\bin\run.bat –c all, 在FreeBSD运行的命令为%JBOSS_HOME%\bin\run.sh –c all
端口冲突问题
JBoss以ALL模式启动时候, 有时可能与某些应用程序冲突. 例如Firefox和MSN(曾遇到以上2这个应用程序端口冲突). 利用netstat –ano 来查看现在访问网络端口的应用程序的PID. 然后利用任务管理器去查找相应的程序,结束即可.
FreeBSD安装问题
在FreeBSD下安装JBoss后, ALL模式并不能正常运行. 需要调整几个参数, 才能运行.进入%JBOSS_HOME%server/all/deploy目录.
<!--[if !supportLists]-->(1) <!--[endif]-->cluster-service.xml文件
<UDP …enable_bundling="false" max_bundle_size="64000 max_bundle_timeout="30"…>
改为
<UDP …enable_bundling="false" max_bundle_size="8000 max_bundle_timeout="30"…>;
<TCP enable_bundling="false" max_bundle_size="64000" max_bundle_timeout="30">
改为
<TCP enable_bundling="false" max_bundle_size="8000" max_bundle_timeout="30">
<!--[if !supportLists]-->(2) <!--[endif]-->ejb3-clustered-sfsbcache-service.xml文件
<UDP …enable_bundling="false" max_bundle_size="64000 max_bundle_timeout="30"…>
改为
<UDP …enable_bundling="false" max_bundle_size="8000 max_bundle_timeout="30"…>
<!--[if !supportLists]-->(3) <!--[endif]-->ejb3-entity-cache-service.xml文件
<UDP …enable_bundling="false" max_bundle_size="64000 max_bundle_timeout="30"…>
改为
<UDP …enable_bundling="false" max_bundle_size="8000 max_bundle_timeout="30"…>
<!--[if !supportLists]-->(4) <!--[endif]-->jboss-web-cluster.sar/META-INF/jboss-service.xml文件
<UDP …enable_bundling="false" max_bundle_size="64000 max_bundle_timeout="30"…>
改为
<UDP …enable_bundling="false" max_bundle_size="8000 max_bundle_timeout="30"…>;
<TCP enable_bundling="false" max_bundle_size="64000" max_bundle_timeout="30">
改为
<TCP enable_bundling="false" max_bundle_size="8000" max_bundle_timeout="30">
附录
附录一
mod-jk.conf文件
//加载mod_jk模块
LoadModule jk_module modules/mod_jk.so
//设置worker配置文件
JkWorkersFile conf/workers.properties
//设置日志记录位置
JkLogFile logs/mod_jk.log
//设置日志记录级别
JkLogLevel info
//设置日志记录格式
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
//设置提交SSL KEY SIZE
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
//设置请求格式
JkRequestLogFormat "%w %V %T"
//设置负载转发请求
JkMount /ClusterTest/* loadbalancer
//设置负载转发文件
JkMountFile conf/uriworkermap.properties
uriworkermap.properties文件
/jmx-console=loadbalancer
/jmx-console/*=loadbalancer
/web-console=loadbalancer
/web-console/*=loadbalancer
workers.properties文件
# 定义workers 列表
worker.list=loadbalancer, node1, node2
# 定义 Node1
# 修改主机IP地址等参数
worker.node1.port=8009
worker.node1.host=localhost
worker.node1.type=ajp13
worker.node1.lbfactor=1
# 定义 Node2
# 修改主机IP地址等参数
worker.node2.port=8009
worker.node2.host=192.168.0.180
worker.node2.type=ajp13
worker.node2.lbfactor=1
# 设置Load-balancing 行为
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=node1, node2
worker.loadbalancer.sticky_session=1
附录二
jboss-web.xml文件
<jboss-web>
<replication-config>
<replication-trigger>
SET_AND_NON_PRIMITIVE_GET
</replication-trigger>
<replication-granularity>SESSION</replication-granularity>
<replication-field-batch-mode>
true
</replication-field-batch-mode>
</replication-config>
</jboss-web>
文章出处:http://www.diybl.com/course/3_program/java/javajs/2007923/73054.html