G时代网站 www.gtime.cn 负载均衡集群方案

为了对得起早上那个BSD fans的热情,把我上次给公司做的负载均衡集群方案给大家参考参考,有的人就很不愿意把自己做的东西写出来,因为知道的人越多,含金量就越少了,我倒是觉得,知道的人越多,才能萌生出更多的ideas,说老实话我不喜欢做SA,我讨厌机房的灰尘和风扇的呜呜声,我只是很喜欢FreeBSD这个纯洁的操作系统,就像一个裸体一样(这话不是我说的)。

G时代网站 www.gtime.cn 负载均衡集群方案

应用背景
伴随着全球企业日益重视竞争和协作的统一,企业开始对系统的高可用性应用提出了越来越高的要求。类unix操作系统以其低廉的价格,稳定的性能以及强大的服务器集群功能在市场中占有越来越大的比例.

方案介绍
服务器集群就是将一组独立的服务器作为单一系统进行管理,以此来实现更高的可靠性。整个系统中每一台服务器都处于相互的监视状态当中,一旦出现某一服务器宕机,或者其他不能正常工作的现象,另外的服务器就可以立即接管其所有服务,使所有用户能够正常工作。服务器集群基本架构如下图所示: (图略)

TOMCAT 服务器使用IP多点传送在集群中的服务器例程间进行一对多的通讯,IP多点传送是一种能够让多服务器向指定IP地址和端口号进行订阅并且监听消息的广播技术(多点传送IP地址范围从224.0.0.0 到239.255.255.255)。在集群中的每个服务器都使用多点传送广播特定的 heartbeat消息,通过监视这些 heartbeat消息,在集群中的服务器例程判断什么时候服务器例程失效。在服务器通讯中使用IP多点传送的一个缺点是他不能保证这些消息被确实接收到了。
上面的图例已经表明了网站的基本架构,前台使用Apache作为负载均衡和缓存,后台使用三台tomcat进行集群,在当前的tomcat版本中,只有all to all的会话复制,所以官方文档只建议做2到4台的集群,下一个发行版本中tomcat会推出适用于大型集群系统的session复制体系。

服务器环境以及软件平台
FreeBSD5.4(http://www.freebsd.org) ,
j2sdk1.4.2(http://www.sun.com)
Apache2.2.0(http://httpd.apache.org)
Tomcat5.0.30(http://tomcat.apache.org)
一共四台服务器,221.5.234.140(192.168.0.1)作为www前台代理用于负载均衡和内部网关用于集群,192.168.0.2,192.168.0.3,192.168.0.4,分别命名为2号服务器,3号服务器,4号服务器,三台主机各启动一个tomcat例程。
首先安装各种软件,均使用默认安装,这里不做赘述,安装完成后的路径为
JAVA JDK:/usr/local/jdk1.4.2
Tomcat:/usr/local/jakarta-tomcat5.0/
Apache:/usr/local/httpd

全部方案分为四个部分:集群,负载均衡,输出压缩,存储服务器

附:网关设置,web访问统计,内网服务器状态监视,服务器代码管理,服务器操作系统管理。

配置过程:
集群部分:
Tomcat:
1.本方案中,原计划使用3个独立IP做集群以便于管理,但是因为分配的IP不在一个子网当中,无法使用多播,所以改用私有IP做内部集群,因为后台的三个tomcat也不对互联网开放服务,前台服务器一共有两张网卡,其中一张使用一个公网IP221.5.234.140,另外一张使用私有IP192.168.0.1,同时开启网关(附后)
2.使用tomcat自带的session复制体系,取消server.xml当中“<Cluster className=”部分的注释,对于集群使用相同的多播地址224.0.0.4。
3.在每个WWW网站应用中的web.xml文件,添加<distributable/>元素。
关闭tomcat的http connector端口,打开tomcat ajp13端口供Apache调用,同时对ajp13端口进行一些细微调节。
4.前台服务器上的apache和后台三台PC机上的tomcat相应端口如下表所示。(表略)
5.在tomcat启动文件startup.sh中设置JAVA_HOME=/usr/local/jdk1.4.2环境变量;启动tomcat

Tomcat范例配置文件如下:(配置文件略)

负载均衡部分:

安装Apache2.2.0,编译时加入ajp代理以及反向代理参数以及负载均衡参数:
./configure –enable-proxy –enable-proxy-ajp –enable-proxy-balancer
本方案中,221.5.234.140上的Apache代理后台的三个tomcat(TC02,TC03,TC04)。
在221.5.234.140上的Apache的配置文件中写入
<Proxy balancer://gtCluster> #定义均衡服务器集群名,下同
BalancerMember ajp://192.168.0.2:8009
BalancerMember ajp://192.168.0.3:8009
BalancerMember ajp://192.168.0.4:8009
</Proxy>
<Location />
ProxyPass balancer://gtCluster/ #代理通过该集群名,下同
</Location>
表示221.5.234.140这台主机的Apache使用ajp13模块代理192.168.0.2,192.168.0.3,192.168.0.4上的三个Tomcat,存储服务器和www前台代理放置于同一主机,所以需要设置虚拟主机。

虚拟主机设置如下:
修改/usr/local/httpd/conf/extra/httpd-vhosts.conf,创建基于域名的虚拟主机
NameVirtualHost *:80 #定义主机类型,主机端口
<VirtualHost *:80>
Servername storage.gtime.cn #定义存储服务器域名
CustomLog logs/storage.gtime.cn_access_log combined
<Directory “/files”> #定义存储服务器根路径
AllowOverride None
Options None
</Directory>
DocumentRoot /files
Alias /awstatsclasses “/usr/local/httpd/cgi-bin/wwwroot/classes/” #web日志统计分析软件用
Alias /awstatscss “/usr/local/httpd/cgi-bin/wwwroot/css/” #web日志统计分析软件用
Alias /awstatsicons “/usr/local/httpd/cgi-bin/wwwroot/icon/” #web日志统计分析软件用
ScriptAlias /awstats/ “/usr/local/httpd/cgi-bin/wwwroot/cgi-bin/” #web日志统计分析软件用
</VirtualHost>

<VirtualHost *:80>
Servername www.gtime.cn #定义WWW前台代理域名
CustomLog logs/www.gtime.cn_access_log combined
<Proxy balancer://gtCluster>
BalancerMember ajp://192.168.0.2:8009
BalancerMember ajp://192.168.0.3:8009
BalancerMember ajp://192.168.0.4:8009
</Proxy>
<Location />
ProxyPass balancer://gtCluster/
</Location>
</VirtualHost>

页面输出压缩部分:
使用Apache的deflate模块进行页面压缩,在编译Apache的时候,加入选项:
–enable-deflate
编译完成之后,在httpd.conf中中加入下列语句:
###############gzip output##################
<IfModule mod_deflate.c>
#如果编译了mod_deflate则调用之
DeflateCompressionLevel 9
#gzip压缩比率,可调整为1到9,数字越大压缩比率越大,服务器负荷越高,客户端PC要求越大。
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-httpd-jsp
#只压缩html,txt,xml.jsp文件
</IfModule>
##########################################
压缩效果是很明显的,未压缩之前的www首页是75.96KB,压缩之后只有11.36KB。

存储服务器部分:
目前将存储服务器和www代理服务器放置于同一硬件设备上,存储服务器域名为storage.gtime.cn,后台更新程序亦放置于该服务器,所以存储服务器上运行有一个Tomcat,导致必须使用虚拟主机来区分对www.gtime.cn:80和storage.gtime.cn:80的访问,虚拟主机设置如前文所述。

附:
网关设置
网关NAT选用Freebsd自带的IPFILTER,重新编译操作系统内核,在编译系统内核时加入如下选项:
options IPFILTER #编译加入IPFILTER
options IPFILTER_LOG
options BRIDGE
编译内核并且安装完之后,在系统配置文件中加入如下选项
####rc.conf
gateway_enable=”YES” #启用网关
ipfilter_enable=”YES” #启用ipfilter
ipfilter_flags=””
ipmon_enable=”YES”
ipmon_flags=”-Dsvn”
ipnat_enable=”YES” #启用IPNAT,以便将内网服务映射到外网
设置IPNAT:
建立IPNAT启动文件:
vi /usr/local/etc/rc.d/ipnat.sh
#!/bin/sh
[ -x /sbin/ipnat ] && /sbin/ipnat -CF -f /etc/ipnat.rules && ipf=-y && echo -n ‘ipnat’
建立IPNAT规则:注:fxp0和em0各代表一张网卡
map fxp0 192.168.0.0/24 -> 221.5.234.140/32 #建立192.168.0.0子网
map em0 192.168.0.0/24 -> 221.5.234.140/32
######ftp######将192.168.0.2服务器的21端口映射到221.5.234.140的xxxx端口,以下类似######
rdr fxp0 221.5.234.140/32 port xxxx -> 192.168.0.2 port 21 tcp
rdr em0 221.5.234.140/32 port xxxx -> 192.168.0.2 port 21 tcp
rdr fxp0 221.5.234.140/32 port xxxx -> 192.168.0.3 port 21 tcp
rdr em0 221.5.234.140/32 port xxxx -> 192.168.0.3 port 21 tcp
rdr fxp0 221.5.234.140/32 port xxxx -> 192.168.0.4 port 21 tcp
rdr em0 221.5.234.140/32 port xxxx -> 192.168.0.4 port 21 tcp
######ssh#######将192.168.0.2服务器的22端口映射到221.5.234.140的xxxx端口,以下类似##
rdr fxp0 221.5.234.140/32 port xxxx -> 192.168.0.2 port 22 tcp
rdr em0 221.5.234.140/32 port xxxx -> 192.168.0.2 port 22 tcp
rdr fxp0 221.5.234.140/32 port xxxx -> 192.168.0.3 port 22 tcp
rdr em0 221.5.234.140/32 port xxxx -> 192.168.0.3 port 22 tcp
rdr fxp0 221.5.234.140/32 port xxxx -> 192.168.0.4 port 22 tcp
rdr em0 221.5.234.140/32 port xxxx -> 192.168.0.4 port 22 tcp
#######apache######将192.168.0.2服务器的80端口映射到221.5.234.140的xxxx端口,以下类似##
rdr fxp0 221.5.234.140/32 port xxxx -> 192.168.0.2 port 80 tcp
rdr em0 221.5.234.140/32 port xxxx -> 192.168.0.2 port 80 tcp
rdr fxp0 221.5.234.140/32 port xxxx -> 192.168.0.3 port 80 tcp
rdr em0 221.5.234.140/32 port xxxx -> 192.168.0.3 port 80 tcp
rdr fxp0 221.5.234.140/32 port xxxx -> 192.168.0.4 port 80 tcp
rdr em0 221.5.234.140/32 port xxxx -> 192.168.0.4 port 80 tcp