集群是指把不同的服务器集中在一起,组成一个服务器集合,这个集合给客户端提供一个虚拟的平台,使客户端在不知道服务器集合结构的情况下可以对这一服务器集合进行部署应用,获取服务等操作。集群是企业应用的主要特点,它可以提供:
不管是扩展自己的集群的节点数,还是配置负载均衡、容错,集群中各节点之间状态必须保持一致,集群中状态保持一致需要借助与缓存机制实现(JBoss使用JGroups,Infinispan我们在后面的系列介绍)。如下图为一传统企业应用集群模式:
图-1传统企业应用集群
1. 客户端浏览器发送请求
2. 负载均衡器转发请求到节点1
3. 节点1处理业务时发生异常
4. 负载均衡切换请求到节点2
5. 节点2完成业务请求返回结果给客户端请求
上述业务请求完成过程中客户端不知道服务器端节点1发生异常。业务能够完成的核心是两个节点之间实时进行着状态复制,而状态复制需要借助于缓存框架和产品(JBoss使用JGroups,Infinispan我们在后面的系列介绍)。
Apache httpd作为负载均衡器和后台中间件服务器构建构架高可用企业应用集群是非常普遍的一种方式,当前主要三大中间件JBoss,Weblogic,Websphere都支持Apache httpd作为负载均衡器。JBoss做为开源的产品是最被广泛使用的中间件,JBoss在被Red Hat公司收购后又推出企业版EAP(EnterpriseApplication Platform),从而使JBoss在许多核心业务领域被使用。比如印度铁路系统底层为JBoss; 2012伦敦奥运会系统底层是4台JBoss的集群等。如下我们将使用JBoss和Apache httpd给出一个构建高可用企业应用集群的解决方案。
本方案使用开源JBoss社区的产品搭建一个高可用企业集群环境,负载均衡器位于集群节点之上。通过本方案我们可以体会到企业应用的高可用性主要是因为集群节点之间状态保持同步,即会话复制(Session Replication),而如何进行会话复制则是本书主要论述的主题。我们先给出本方案的架构图:
图-2 方案设计架构
如上,使用JBoss AS7做为集群节点,为了简单我们只使用两台JBoss,即集群中就有两个节点。Apache httpd 和 mod_cluster 做负载均衡器,mod_cluster作为Apache的插件模块负责连接Apache和JBoss,根据负载均衡策略分发和请求给后台JBoss,所以我们可以将Apache httpd 加mod_cluster作为负载均衡器。
本方案会话复制是通过JBoss社区产品JGroups和第二代JBossCache产品Infinispan完成的,但本处我们不对JGroups和Infinispan做任何探讨,我们将在后面的系列详细讨论JGroups和Infinispan。
另外,本方案是在开源Linux操作系统Fedora 15上进行,我们列出本方案使用的硬件和软件,三台物理机器,内存4GB或以上,安装Fedora 15后IP地址分别为10.66.192.48,10.66.192.231,10.66.192.232,我们分别对这三台物理机器做相应的安装如下:
接下来我们将从方案配置,测试应用的安装,及结果分析等方面展开讨论此方案。
在 JBoss 社区mod_cluster页面(http://www.jboss.org/mod_cluster)选择下载(Downloads),选定相应的版本(1-2-0-Final),弹出页面会列出所以相关的 Java 模块(主要用来与JBoss AS 6以及之前的版本完成集群配置)、编译完成的Apachehttpd、Apache httpd端动态模块包。根据您的平台选择相关包进行下载我们会得到如下文件:
解压mod_cluster-1.2.0.Final-bin.tar.gz我们会得到一些用于JBoss AS 6及之前版本的Java组件和测试例子等。
解压mod-cluster-1.0.0-linux2-x86-ssl.tar.gz我们会得到一个安装配置完成的httpd位于opt/jboss目录下。这里我们不使用此安装,我们使用从操作系统层面以安装包方式安装,如下文所示。
解压 mod_cluster-1.2.0.Final-linux2-x86-so.tar.gz ,我们会得到如下包:同样如下文所示我们需要将这些动态包拷贝到Apache httpd 的modules 目录下,这些包用来维护、管理Apache httpd与后台JBoss之间的连接,通信。
请参照系列一 Apache httpd 安装(http://blog.csdn.net/kylinsoong/article/details/12291173)
编辑httpd/conf/httpd.conf,让httpd监听在10.66.192.48:80上:
Listen 10.66.192.48:80
拷贝mod_cluster所有.so文件(mod_advertise.so ,mod_manager.so ,mod_proxy_cluster.so,mod_slotmem.so)到httpd/modules目录:
cp *.so /etc/httpd/modules
编辑httpd/conf/httpd.conf,注释掉mod_proxy_balancer模块,以为此模块与mod_cluster相关模块不兼容:
# LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
在httpd/conf.d目录下创建JBoss_HTTP.conf文件,将如下内容添加到此文件:
# add mod_cluster reference module
LoadModule slotmem_module modules/mod_slotmem.so
LoadModule manager_module modules/mod_manager.so
LoadModule proxy_cluster_module modules/mod_proxy_cluster.so
LoadModule advertise_module modules/mod_advertise.so
Listen 10.66.192.48:6666
Order deny,allow
Allow from all
SetHandler mod_cluster-manager
Order deny,allow
Allow from all
KeepAliveTimeout 60
MaxKeepAliveRequests 0
AdvertiseFrequency 5
ManagerBalancerName kylincluster
ServerAdvertise Off
EnableMCPMReceive On
我们可以通过如下三种方式添加proxy-list,balancer完成JBoss端集群配置:
1. 修改配置文件
编辑/standalone/configuration/standalone-ha.xml文件,找到urn:jboss:domain:modcluster部分,修改mod-cluster-config的属性如下:
保存修改文件即完成配置。
2. 通过Web管理界面
以standalone-ha.xml模式(./standalone.sh -c standalone-ha.xml)启动JBoss后登录管理界面(http://localhost:9990/console),选择Profile,Web,mod_cluster,在弹出界面点击相关按钮,编辑balancer值为kylinBalancer,proxy-list值为10.66.192.48:6666,sticky-session值为true,点击保存按钮即完成配置。
3. 通过命令行管理窗口
以standalone-ha.xml模式(./standalone.sh -c standalone-ha.xml)启动JBoss后进入到命令行界面,依次执行如下命令:
/subsystem=modcluster/mod-cluster-config=configuration/:write-attribute(name=balancer,value=kylinBalancer)
/subsystem=modcluster/mod-cluster-config=configuration/:write-attribute(name=sticky-session,value=true)
/subsystem=modcluster/mod-cluster-config=configuration/:write-attribute(name=proxy-list,value=10.66.192.48:6666)
说明:以上三个步骤中提及的proxy-list,balancer的值需要与Apache httpd端配置想对应,我们应该依次对两个节点进行配置
Linux操作系统下使用如下命令完成启动Apache httpd:
service httpd start
2. 使用如下命令依次启动JBoss两个节点
./standalone.sh -c standalone-ha.xml -b 10.66.192.231 -bmanagement 10.66.192.231 -u 239.255.100.100 -Djboss.node.name=node1 -Djboss.mod_cluster.jvmRoute=node1
./standalone.sh -c standalone-ha.xml -b 10.66.192.232 -bmanagement 10.66.192.232 -u 239.255.100.100 -Djboss.node.name=node2 -Djboss.mod_cluster.jvmRoute=node2
启动完成分别登录如下界面测试:
本部分包括部署测试应用,容错性和高可用性测试,结果分析三个方面去说明。
使用git clone 我们本系列所需的测试代码(参照系列一github客户端安装部分),clone完成后进入系列二目录,也是我们这里所使用的测试工程,具体:
cd csdn/2/
在该目录下执行Maven(
Maven安装参照系列一Maven安装部分)编译
系列二工程:
mvn clean install
编译完成后会生成webcluster-session-replication.war,路径为csdn/2/target/webcluster-session-replication.war,
分别部署webcluster-session-replication.war到两个JBoss节点上(图-2方案设计架构中IP地址为10.66.192.231和10.66.192.232机器)。检查两个节点JBoss Console端的日志输出,如果没有异常显示则证明测试应用部署完成。部署成功后我们在Apache httpd所在的机器(IP地址为10.66.192.48)访问应用,具体使用http://10.66.192.48/sessionReplication访问测试应用,在打开的页面中点击蓝色添加按钮添加内容三次,结果显示如下图所示:
图-3 应用测试截图
1. 负载均衡器将请求分发给了节点一
如上图所示,处理业务逻辑的服务器是10.66.192.231/node1机器,也就是说负载均衡器(Apache httpd 和 mod_cluster) 分发请求到10.66.192.231 节点1 JBoss。
2. 测试集群间的状态复制
由于节点1和节点2进行着状态复制,所以添加在节点1上的三条信息也复制到节点2,所以如果我们接下来通过8080端口直接访问节点2(http://10.66.192.232:8080/sessionReplication)会看到之前通过Apache端(http://10.66.192.48/sessionReplication)添加的内容已经存在于节点2上。
3. 容错性高可用性测试
如上负载均衡器(10.66.192.48)将请求分发给节点1(10.66.192.231),接下来我们关闭节点1JBoss,我们会发现请求(http://10.66.192.48/sessionReplication)会自动切换到节点2(10.66.192.232),上述自动切换完成过程中客户端不知道服务器端节点1发生异常,这体现了集群的容错性高可用性测试。
我们通过如下图中所示的4步解释说明Apache httpd和JBoss构架高可用集群环境中为什么负载均衡器(10.66.192.48)能够将请求分发到工作集群节点(10.66.192.231和10.66.192.232)上,我们基于图-4:
图-4负载均衡器分发请求到集群节点
第一步:负载均衡器将自己广播到多播组,告诉JBoss集群节点"I'm here"
第二步:JBoss集群节点通过多播组发现负责均衡器,并加入集群
第三步:使用MCPM协议获取集群节点信息,连接或断开节点
第四步:使用ajp/http/https转发请求到集群节点
分析如上结果,节点1和节点2之间进行会话状态同步是通过JBoss缓存产品Infinispan和JGroups完成的,Infinispan和JGroups是JBoss社区优秀产品,我会在后面的系列做详细介绍。JBoss节点间会话复制大体架构如下图所示:
图-5 Web会话复制过程
JGroups是一个可靠多波通信工具,借助于网络多波通信进行状态复制,Infinispan则基于JGroups之上的分布式缓存。
JBoss集群进行状态复制是因为我们做了如下的配置:
1. JBoss端Infinispan相关配置如下:
...
3. webcluster-session-replication.war/WEB-INF/web.xml端配置:
web.repl-async