相信很多朋友对企业级的负载均衡高可用实例非常感兴趣,此篇文章根据成熟的线上环境而写,旨在帮助大家迅速架构一个企业级的负载均衡高可用的web环境。
此系统架构仅映射内网VIP的80及443端口于外网的Juniper防火墙下,其它端口均关闭,内网所有机器均关闭iptables及ipfw防火墙;外网DNS指向即通过Juniper映射出来的外网地址,而此映射的地址对映的其实是内网VIP地址。这里说下端口的问题,有的朋友可能会很疑惑,这样映射端口行不?通过项目实践得知,这样完全是可行的,php-cgi需要的9000端口及MySQL的3306端口均可走内网,完全不影响业务系统的运行。
另外,我维护的电子商务网站并发大约在1000左右,此时,Nginx+Apache集群运行得非常稳定,尤其是apache,并没有想象中那般弱;其实,在内存足够(>=8G)的情况,测试时不连数据库的话,单台apache+php5能顶得住6000并发,而且相当稳定。在网站升级架构方面,我不赞成全面淘汰生级,锦上添花式的升级会更好。
第一部分:Nginx+Keepalived的说明及环境说明 喜欢看我博客或文章的朋友都知道,我一直主力推崇Nginx+Keepalived作web的负载均衡高可用架构,并积极将其用于项目方案中;Nginx负载均衡作服务器遇到的故障一般有: ①服务器网线松动等网络故障; ②服务器硬件故障从而crash; ③nginx服务死掉; 遇到前二者情况,keeaplived是能起到HA的作用的;然而遇到③种情况就没有办法了,但可以通过shell监控解决这问题,从而实现真正意义上的负载均衡高可用。此篇的最新更新时间为2010年6月25号,下面将其安装步骤详细说明下:
环境: centos5.3(64位)、nginx-0.7.51、keepalived-1.1.15 主nginx负载均衡器:192.168.0.154 辅nginx负载均衡器:192.168.9.155 vip:192.168.0.188
第二部分:分别安装Nginx负载均衡器及相关配置脚本 先安装Nginx负载均衡器,nginx负载的配置就用一般的模板来配置了
1 2 3 4 5 6 7 8 9 10 11 12 13 groupadd www useradd -g www www wget ftp:// ftp.csx.cam.ac.uk/pub/ software/programming/ pcre/pcre-7.8 .tar.gz tar zxvf pcre-7.8 .tar.gz cd pcre-7.8 / ./configure make && make install wget http:// sysoev.ru/nginx/ nginx-0.7 .51 .tar.gz tar zxvf nginx-0.7 .51 .tar.gz cd nginx-0.7 .51 / ./configure --user=www --group=www --prefix=/u sr/local/ webserver/nginx --with-http_stub_status_module --with-http_ssl_module make && make install
配置nginx负载均衡器的配置文件vim /usr/local/nginx/conf/nginx.conf
,此篇文章仅仅只是我的某项目的配置文档,纯80转发;如果对nginx配置有https要求的可参考张宴的相关文章。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 user www wwwworker_processes 8 pid /usr/local/nginx/logs/nginx.pid worker_rlimit_nofile 65535 events { use epoll worker_connections 65535 } http{ include mime.types default_type application/octet-stream server_names_hash_bucket_size 128 client_header_buffer_size 32 k large_client_header_buffers 4 32 k client_max_body_size 8 m sendfile on tcp_nopush on keepalive_timeout 60 tcp_nodelay on fastcgi_connect_timeout 300 fastcgi_send_timeout 300 fastcgi_read_timeout 300 fastcgi_buffer_size 64 k fastcgi_buffers 4 64 k fastcgi_busy_buffers_size 128 k fastcgi_temp_file_write_size 128 k gzip on gzip_min_length 1 k gzip_buffers 4 16 k gzip_http_version 1.0 gzip_comp_level 2 gzip_types text/plain application/x-javascript text/css application/xml gzip_vary on upstream backend { server 192.168 .1.102 :80 server 192.168 .1.103 :80 server 192.168 .1.105 :80 } server { listen 80 server_name www.yuhongchun027.com location / { root /var /www index index.jsp index.htm index.html proxy_redirect off proxy_set_header Host $host proxy_set_header X-Real-IP $remote_addr proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for proxy_pass http://backend } location /nginx { access_log on auth_basic "NginxStatus" auth_basic_user_file /usr/local/nginx/htpasswd } log_format access '$remote_addr - $remote_user [$time_local ] "$request " ' '$status $body_bytes_sent "$http_referer " ' '"$http_user_agent " $http_x_forwarded_for ' access_log /var /log/access.log access } }
小节:
第一部分和第二部分讲的是如何通过安装Nginx来达到负载均衡后端web集群的过程,Nginx能实现自动切换后端有故障的web服务器;但Nginx负载均衡器出了问题怎么办呢,它们之间是如何实现无故障转移的呢?
第三部分:安装Keepalived,让其分别作web及Nginx的HA 安装keepalived,并将其做成服务模式,方便以后调试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 wget http: #tar zxvf keepalived-1.1 .15 .tar.gz #cd keepalived-1.1 .15 #./configure --prefix=/u sr/local/ keepalived #make #make install #cp /usr/ local/keepalived/ sbin/keepalived /u sr/sbin/ #cp /usr/ local/keepalived/ etc/sysconfig/ keepalived /etc/ sysconfig/ #cp /usr/ local/keepalived/ etc/rc.d/i nit.d/keepalived / etc/init.d/ #mkdir /etc/ keepalived #cd /etc/ keepalived/ vim keepalived.conf ! Configuration File for keepalived global_defs { notification_email { yuhongchun027@163 .com } notification_email_from keepalived@chtopnet.com smtp_server 127.0 .0.1 smtp_connect_timeout 30 router_id LVS_DEVEL } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 mcast_src_ip 192.168 .0.154 <==主nginx的IP地址 priority 100 advert_int 1 authentication { auth_type PASS auth_pass chtopnet } virtual_ipaddress { 192.168 .0.188 <==vip地址 } } #service keepalived start
我们来看一下日志:
1 2 3 4 5 6 7 [root@ltos ~]# tail /var/log /messages Oct 6 03 :25 :03 ltos avahi-daemon[2306 ]: Registering new address record for 192.168 .0 .188 on eth0. Oct 6 03 :25 :03 ltos avahi-daemon[2306 ]: Registering new address record for 192.168 .0 .154 on eth0. Oct 6 03 :25 :03 ltos avahi-daemon[2306 ]: Registering HINFO record with values 'I686' /'LINUX' . Oct 6 03 :25 :23 ltos avahi-daemon[2306 ]: Withdrawing address record for fe80::20 c:29 ff:feb9:eeab on eth0. Oct 6 03 :25 :23 ltos avahi-daemon[2306 ]: Withdrawing address record for 192.168 .0 .154 on eth0. Oct 6 03 :25 :23 ltos avahi-daemon[2306 ]: Host name conflict , retrying with <ltos-31 >
很显然vrrp已经启动,我们还可以通过命令来检查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 [root@ltos html] 1 : lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue link/loopback 00 :00 :00 :00 :00 :00 brd 00 :00 :00 :00 :00 :00 inet 127.0 .0.1 /8 scope host lo inet6 ::1 /128 scope host valid_lft forever preferred_lft forever 2 : eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 00 :0 c:29 :ba:9 b:e7 brd ff:ff:ff:ff:ff:ff inet 192.168 .0.154 /24 brd 192.168 .0.255 scope global eth0 inet 192.168 .0.188 /32 scope global eth0 inet6 fe80::20 c:29 ff:feba:9 be7/64 scope link valid_lft forever preferred_lft forever 3 : sit0: <NOARP> mtu 1480 qdisc noop link/sit 0.0 .0.0 brd 0.0 .0.0
说明vip已经启动,这样主服务器就配置好了,辅机的配置大致一样,除了配置文件有少部分的变化,下面贴出辅机的配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ! Configuration File for keepalived global_defs { notification_email { yuhongchun027@ 163. com } notification_email_from keepalived@ chtopnet.com smtp_server 127.0 .0 .1 smtp_connect_timeout 30 router_id LVS_DEVEL } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 mcast_src_ip 192.168 .0 .155 <== 辅nginx的IP的地址 priority 100 advert_int 1 authentication { auth_type PASS auth_pass chtopnet } virtual_ipaddress { 192.168 .0 .188 } }
第四部分:针对Keepalived的不足,用Nginx_pid.sh来监控nginx进程,实现真正意义上的负载均衡高可用。 针对Nginx+Keepalived,编写nginx监控脚本nginx_pid.sh,此脚本思路其实也很简单,即放置在后台一直监控nginx进程;如进程消失,尝试重启nginx,如是失败则立即停掉本机的keepalived服务,让另一台负载均衡器接手,此脚本直接从生产环境下载:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 vim /root/nginx_pid.sh while : do nginxpid=`ps -C nginx --no-header | wc -l` if [ $nginxpid -eq 0 ];then /usr/local/nginx/sbin/nginx sleep 5 nginxpid=`ps -C nginx --no-header | wc -l` if [ $nginxpid -eq 0 ];then /etc/init.d/keepalived stop fi fi sleep 5 done
然后置于后台运行sh /root/nginx_pid.sh &
,这种写法是错误的,这样你用root用户logout后,此进程会消失;正确写法为nohup/bin/bash /root/nginx_pid.sh &
,附带下注释:如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用nohup命令。该命令可以在你退出root帐户之后继续运行相应的进程。nohup就是不挂起的意思(no hang up),哈哈,差点老马失蹄了。
后记:
我的线上环境网络非常复杂,这也是LVS+Keepalived失败的原因。目前此套架构在1000并发的电子商务网站非常稳定,带来的直接影响就是nginx_backup一直处于闲置状态。相对于张宴的双机轮询而言,我感觉他的可能更加完美,因为目前我的Nginx仅仅只做了负载均衡器,如果以后有机会我会尝试做负载均衡器/反向代理加速。