1、 前言
集群是指把不同的服务器集中在一起,组成一个服务器集合,这个集合给客户端提供一个虚拟的平台,使客户端在不知道服务器集合结构的情况下对这一服务器集合进行部署应用、获取服务等操作。集群是企业应用的主要特点,它可以提供:
高扩展性:可以根据自己业务需求添加任意多的服务器到集群;
高可用性:使用透明的负载均衡和容错机制,对客户端隐藏集群内部的错误。
下图为一传统企业应用集群模式:
图中各个步骤描述如下:
1. 客户端浏览器发送请求
2. 负载均衡器转发请求到节点1
3. 节点1处理业务时发生异常
4. 负载均衡切换请求到节点2
5. 节点2完成业务请求返回结果给客户端请求
上述业务请求完成过程中客户端不知道服务器端节点1发生异常,业务能够完成的核心是两个节点之间实时进行着状态复制。
2、高可用集群环境方案简介
Apache httpd作为负载均衡器和后台应用服务器构建构架高可用企业应用集群是非常普遍的一种方式。JBoss做为开源的产品是最被广泛使用的中间件,且JBoss支持Apache httpd作为负载均衡器。JBoss在被Red Hat公司收购后又推出企业版EAP(Enterprise Application Platform),从而使JBoss在许多核心业务领域被广泛使用。例如:印度铁路系统底层Web容器为JBoss;2012伦敦奥运会门票系统底层Web容器是4台JBoss的集群等。
本方案使用开源JBoss社区的产品搭建一个高可用企业集群环境,负载均衡器位于集群节点之上。通过本方案我们可以体会到企业应用的高可用性,而高可用性主要依赖于集群节点之间session的同步,即会话共享(Session Replication),而如何进行会话共享则是本文主要论述的主题。如下,我们给出本方案的架构图:
如上图所示,使用jboss-eap-6.1.0做为集群节点,为了简单我们只使用两台JBoss,即集群中就有两个节点。Apache httpd 和 mod_cluster 做负载均衡器,mod_cluster作为Apache的插件模块负责连接Apache和JBoss,根据负载均衡策略分发请求给后台JBoss。
本方案是在开源Linux操作系统Red Hat ES6上进行,我们列出本方案所使用机器的基本情况:
负载均衡器 – 安装JDK1.7、Apache Httpd、Mod_cluster,IP:192.168.31.22;
JBoss Server1 – 安装JDK1.7、JBoss EAP6,节点名称node1,IP:192.168.31.22;
JBoss Server2 – 安装JDK1.7、JBoss EAP6,节点名称node2,IP:192.168.31.21;
3、具体配置
3.1 mod_cluster下载安装
下载mod_cluster-1.2.0.Final-linux2-x64-ssl.tar.gz,解压压缩包,在mod_cluster-1.2.0.Final-linux2-x64-ssloptjbosshttpdlibhttpdmodules下寻找:
mod_advertise.so mod_manager.so mod_proxy_cluster.so mod_slotmem.so |
这四个包是用来维护、管理Apache httpd与JBoss之间的连接、通信。将这四个动态包拷贝到Apache httpd 的modules 目录下,即/etc/httpd/modules下。
3.2 Apache httpd安装配置
3.2.1 安装
下载apache 2.2.15并编译安装 # tar -zxvf httpd-2.2.15.tar.gz # cd httpd-2.2.15 #./configure --prefix=/usr/local/apache2 --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --with-pcre=/usr/local/pcre # make # make install # service httpd start |
3.2.2 配置
(1)编辑httpd.conf
#vim /etc/httpd/conf/httpd.conf。让httpd监听在192.168.31.22:80上:
Listen 192.168.31.22:80 |
注释掉mod_proxy_balancer模块,因为此模块与mod_cluster相关模块不兼容:
#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so |
(2)创建JBoss_HTTP.conf
# vim /etc/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 192.168.31.22:6666 <VirtualHost 192.168.31.22:6666> <Directory /> Order deny,allow Allow from all </Directory> <Location /mod_cluster-manager> SetHandler mod_cluster-manager Order deny,allow Allow from all </Location> KeepAliveTimeout 60 MaxKeepAliveRequests 0 AdvertiseFrequency 5 ManagerBalancerName kylincluster ServerAdvertise Off EnableMCPMReceive On </VirtualHost> |
3.2.3 重启服务
#service httpd restart 若启动成功则表明配置正确。
3.3 JBoss配置
我们通过Web界面添加proxy-list、balancer完成JBoss端集群配置。
3.2.1 为JBoss添加管理用户
进入到JBoss_HOME/bin下,执行./add-user.sh,按照提示依次选择用户类型(管理用户、应用用户)、用户名、密码等。注意,从jboss-eap-6.1.0开始,JBoss管理用户的密码必须包含数字、字母和其余字符,且长度大于8字符。
3.2.2 登录管理界面进行配置
以standalone-ha.xml模式(./standalone.sh -c standalone-ha.xml)启动JBoss后登录管理界面(http://192.168.31.22:9990/console),选择Profile,Web,mod_cluster,在弹出界面点击相关按钮,编辑balancer值为kylinBalancer,proxy-list值为192.168.31.22:6666,sticky-session值为true,sticky-session-force值为false,点击保存按钮即完成配置。具体细节见下两图:
3.2.3 JBoss session复制配置
进入到JBoss_HOME/standalone/deployments/s*.war/WEB-INF/,编辑web.xml。在web.xml中添加:
<distributable/> |
3.4 集群启动
3.4.1 重新启动Apache Httpd
#service httpd restart |
3.4.1 依次启动JBoss的两个节点
启动Node1
#./standalone.sh -c standalone-ha.xml -b 192.168.31.22 -bmanagement 192.168.31.22 -Djboss.node.name=node1 -Djboss.mod_cluster.jvmRoute=node1 |
启动Node2
#./standalone.sh -c standalone-ha.xml -b 192.168.31.21 -bmanagement 192.168.31.21 -Djboss.node.name=node2 -Djboss.mod_cluster.jvmRoute=node2 |
4、方案测试、验证
4.1 登录mod_cluster管理界面
4.2 登录应用服务器
以代理服务器IP、Port登录应用服务器,例如:http://192.168.31.22:6666/starott_up_client/login ,能够登录成功。
4.3 高可用性验证
以代理服务器IP、Port登录应用服务器,例如:http://192.168.31.22:6666/starott_up_client/login。观察两个真实节点中的日志文件,将正在提供服务的节点(例如节点1)停掉,观察网页是否正常提供服务,即节点1上的session复制到其余节点,继续提供服务。
5、注意事项
5.1 httpd服务启动问题
(1)Apache Httpd在启动时可能会遇到端口占用问题,采用如下命令,找到占用该端口的进程,杀掉:
#netstat -anp | grep 80 #kill -9 12993 |
(2)在启动时也会遇到权限问题,例如:
Starting httpd: (13)Permission denied: make_sock: could not bind to address 192.168.31.22:6666 no listening sockets available, shutting down |
解决办法为关闭selinux:
setenforce 0 |
5.2 不同机器session复制问题
如果本地服务器上可以进行session复制,而不可以同局域网内部的其他节点进行session复制,那么可能是由于两台机器的时间不同步,导致session复制失败。
5.3 sticky-session解析
sticky-session是指session是否具有黏着性。如果false则代表session为非黏着性session,也就是说如果第一次的请求会话是在node1这个节点,那么在下一次请求的时候就有很大的不确定性,很有可能就到了node2这个节点上。而黏着性session就代表着一次请求,只要会话不变、浏览器不关闭,那么在这一整个的长回话session请求中,自始至终都是同一个节点为这个长久会话提供服务,如果不是特殊原因,绝对不会将节点切换到别的机器上。
如果JBoss配置了相关集群的信息,那么其中一个节点宕机之后,请求就会自动切换到另一个节点上去,Session信息也会复制过去,保证客户的会话信息不会丢失。