LAMP之路

不积跬步,无以至千里!

企业级web负载均衡完美架构

2012-10-18 一抹阳光 环境架设

第一部分:Nginx+Keepalived的说明及环境说明

喜欢看我博客或文章的朋友都知道,我一直主力推崇Nginx+Keepalived作web的负载均衡高可用架构,并积极将其用于项目方案 中;Nginx负载均衡作服务器遇到的故障一般有①服务器网线松动等网络故障;②服务器硬件故障从而crash;③nginx服务死掉;遇到前二者情 况,keeaplived是能起到HA的作用的;然而遇到③种情况就没有办法了,但可以通过shell监控解决这问题,从而实现真正意义上的负载均衡高可 用。此篇的最新更新时间为2010年6月25号,下面将其安装步骤详细说明下:

环境:

1.           centos5.3(64位)、nginx-0.7.51、keepalived-1.1.15
2.           主nginx负载均衡器:192.168.0.154
3.           辅nginx负载均衡器:192.168.9.155
4.           vip:192.168.0.188

第二部分:分别安装Nginx负载均衡器及相关配置脚本

先安装Nginx负载均衡器,nginx负载的配置就用一般的模板来配置了

1.           #添加运行nginx的用户和组www
2.           groupadd www
3.           useradd -g www www
4.           wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-7.8.tar.gz
5.           tar zxvf pcre-7.8.tar.gz
6.           cd pcre-7.8/
7.           ./configure  #实测中报错:no acceptable C compiler found in $PATH。解决:没有安装GCC组件的原因,执行命令:sudo yum -y install gcc* make*
8.           make && make install
9.           wget http://sysoev.ru/nginx/nginx-0.7.51.tar.gz
10.       tar zxvf nginx-0.7.51.tar.gz
11.       cd nginx-0.7.51/
12.       ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module  #实测中报错:SSL modules require the OpenSSL library.执行命令:yum -y install openssl openssl-devel
13.       make && make install
14.       #实测中需要关闭centos防火墙才能正常访问网站,命令service iptables stop

配置nginx负载均衡器的配置文件vim /usr/local/nginx/conf/nginx.conf,此篇文章仅仅只是我的某项目的配置文档,纯80转发;如果对nginx配置有https要求的可参考张宴的相关文章。

1.           user www www;
2.           worker_processes 8;
3.
4.           pid /usr/local/nginx/logs/nginx.pid;
5.           worker_rlimit_nofile 65535;
6.
7.           events
8.           {
9.           use epoll;
10.       worker_connections 65535;
11.       }
12.       http{
13.       include       mime.types;
14.       default_type application/octet-stream;
15.       server_names_hash_bucket_size 128;
16.       client_header_buffer_size 32k;
17.       large_client_header_buffers 4 32k;
18.       client_max_body_size 8m;
19.       sendfile on;
20.       tcp_nopush     on;
21.       keepalive_timeout 60;
22.       tcp_nodelay on;
23.       fastcgi_connect_timeout 300;
24.       fastcgi_send_timeout 300;
25.       fastcgi_read_timeout 300;
26.       fastcgi_buffer_size 64k;
27.       fastcgi_buffers 4 64k;
28.       fastcgi_busy_buffers_size 128k;
29.       fastcgi_temp_file_write_size 128k;
30.       gzip on;
31.       gzip_min_length 1k;
32.       gzip_buffers     4 16k;
33.       gzip_http_version 1.0;
34.       gzip_comp_level 2;
35.       gzip_types       text/plain application/x-javascript text/css application/xml;
36.       gzip_vary on;
37.
38.       upstream backend
39.       {
40.       server 192.168.1.102:80;
41.       server 192.168.1.103:80;
42.       server 192.168.1.105:80;
43.       }
44.       server {
45.       listen 80;
46.       server_name www.yuhongchun027.com;
47.       location / {
48.       root /var/www ;
49.       index index.jsp index.htm index.html;
50.       proxy_redirect off;
51.       proxy_set_header Host $host;
52.       proxy_set_header X-Real-IP $remote_addr;
53.       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
54.       proxy_pass http://backend;
55.       }
56.
57.       location /nginx {
58.       access_log on;
59.       auth_basic "NginxStatus";
60.       auth_basic_user_file /usr/local/nginx/htpasswd;
61.       }
62.
63.       log_format access '$remote_addr - $remote_user [$time_local] "$request" '
64.       '$status $body_bytes_sent "$http_referer" '
65.       '"$http_user_agent" $http_x_forwarded_for';
66.       access_log /var/log/access.log access;
67.
68.       }
69.       }
#实测中Nginx配置文件采用:Nginx负载均衡配置文件.doc中的配置

小节:

第一部分和第二部分讲的是如何通过安装Nginx来达到负载均衡后端web集群的过程,Nginx能实现自动切换后端有故障的web服务器;但Nginx负载均衡器出了问题怎么办呢,它们之间是如何实现无故障转移的呢?

第三部分:安装Keepalived,让其分别作web及Nginx的HA

安装keepalived,并将其做成服务模式,方便以后调试。

1.           wget http://www.keepalived.org/software/keepalived-1.1.15.tar.gz
2.           #tar zxvf keepalived-1.1.15.tar.gz
3.           #cd keepalived-1.1.15
4.           #./configure --prefix=/usr/local/keepalived
5.           #make
6.           #make install
7.           #cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
8.           #cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
9.           #cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
10.       #mkdir /etc/keepalived
11.       #cd /etc/keepalived/
12.
13.       vim keepalived.conf
14.       ! Configuration File for keepalived
15.       global_defs {
16.          notification_email {
17.          yuhongchun027@163.com
18.               }
19.          notification_email_from keepalived@chtopnet.com
20.          smtp_server 127.0.0.1
21.          smtp_connect_timeout 30
22.          router_id LVS_DEVEL
23.       }
24.       vrrp_instance VI_1 {
25.           state MASTER
26.           interface eth0
27.           virtual_router_id 51
28.           mcast_src_ip 192.168.0.154    <==主nginx的IP地址
29.           priority 100
30.           advert_int 1
31.           authentication {
32.               auth_type PASS
33.               auth_pass chtopnet
34.           }
35.           virtual_ipaddress {
36.               192.168.0.188                      <==vip地址
37.           }
38.       }
39.       #service keepalived start

我们来看一下日志:

1.           [root@ltos ~]# tail /var/log/messages
2.           Oct 6 03:25:03 ltos avahi-daemon[2306]: Registering new address record for 192.168.0.188 on eth0.
3.           Oct 6 03:25:03 ltos avahi-daemon[2306]: Registering new address record for 192.168.0.154 on eth0.
4.           Oct 6 03:25:03 ltos avahi-daemon[2306]: Registering HINFO record with values 'I686'/'LINUX'.
5.           Oct 6 03:25:23 ltos avahi-daemon[2306]: Withdrawing address record for fe80::20c:29ff:feb9:eeab on eth0.
6.           Oct 6 03:25:23 ltos avahi-daemon[2306]: Withdrawing address record for 192.168.0.154 on eth0.
7.           Oct 6 03:25:23 ltos avahi-daemon[2306]: Host name conflict, retrying with <ltos-31>

很显然vrrp已经启动,我们还可以通过命令来检查

1.           [root@ltos html]# ip addr
2.           1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue
3.               link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
4.               inet 127.0.0.1/8 scope host lo
5.               inet6 ::1/128 scope host
6.                  valid_lft forever preferred_lft forever
7.           2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
8.               link/ether 00:0c:29:ba:9b:e7 brd ff:ff:ff:ff:ff:ff
9.               inet 192.168.0.154/24 brd 192.168.0.255 scope global eth0
10.           inet 192.168.0.188/32 scope global eth0
11.           inet6 fe80::20c:29ff:feba:9be7/64 scope link
12.              valid_lft forever preferred_lft forever
13.       3: sit0: <NOARP> mtu 1480 qdisc noop
14.           link/sit 0.0.0.0 brd 0.0.0.0

说明vip已经启动,这样主服务器就配置好了,辅机的配置大致一样,除了配置文件有少部分的变化,下面贴出辅机的配置文件:

1.           ! Configuration File for keepalived
2.           global_defs {
3.              notification_email {
4.              yuhongchun027@163.com
5.                   }
6.              notification_email_from keepalived@chtopnet.com
7.              smtp_server 127.0.0.1
8.              smtp_connect_timeout 30
9.              router_id LVS_DEVEL
10.       }
11.       vrrp_instance VI_1 {
12.           state BACKUP
13.           interface eth0
14.           virtual_router_id 51
15.           mcast_src_ip 192.168.0.155              <==辅nginx的IP的地址
16.           priority 99
17.           advert_int 1
18.           authentication {
19.               auth_type PASS
20.               auth_pass chtopnet
21.           }
22.           virtual_ipaddress {
23.               192.168.0.188
24.           }
25.       }

第四部分:针对Keepalived的不足,用Nginx_pid.sh来监控nginx进程,实现真正意义上的负载均衡高可用。

针对Nginx+Keepalived,编写nginx监控脚本nginx_pid.sh,此脚本思路其实也很简单,即放置在后台一直监控 nginx进程;如进程消失,尝试重启nginx,如是失败则立即停掉本机的keepalived服务,让另一台负载均衡器接手,此脚本直接从生产环境下 载:

1.           vim /root/nginx_pid.sh
2.           #!/bin/bash
3.           while  :
4.           do
5.            nginxpid=`ps -C nginx --no-header | wc -l`
6.            if [ $nginxpid -eq 0 ];then
7.             /usr/local/nginx/sbin/nginx
8.             sleep 5
9.              if [ $nginxpid -eq 0 ];then
10.          /etc/init.d/keepalived stop
11.          fi
12.        fi
13.        sleep 5
14.       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仅仅只做了负载均衡器,如果以 后有机会我会尝试做负载均衡器/反向代理加速。

【51CTO.com独家特稿,非经授权谢绝转载,合作媒体转载请注明原文出处及作者!】

另附:创建 Nginx 开机启动脚本

vi /etc/init.d/nginx

加入以下内容

#!/bin/bash

#

# chkconfig: – 85 15

# description: Nginx is a World Wide Web server.

# processname: nginx

nginx=/usr/local/nginx/sbin/nginx

conf=/usr/local/nginx/conf/nginx.conf

case $1 in

       start)

              echo -n “Starting Nginx”

              $nginx -c $conf

              echo ” done”

       ;;

       stop)

              echo -n “Stopping Nginx”

              killall -9 nginx

              echo ” done”

       ;;

       test)

              $nginx -t -c $conf

       ;;

 reload)

              echo -n “Reloading Nginx”

              ps auxww | grep nginx | grep master | awk ‘{print $2}’ | xargs kill -HUP

              echo ” done”

       ;;

 restart)

  $0 stop

  $0 start

       ;;

       show)

              ps -aux|grep nginx

       ;;

       *)

              echo -n “Usage: $0 {start|restart|reload|stop|test|show}”

       ;;

esac

为 nginx.sh 脚本设置可执行属性

chmod +x /etc/init.d/nginx

添加 Nginx 为系统服务(开机自动启动)

chkconfig –add nginx

chkconfig nginx on

启动 Nginx

service nginx start

在不停止 Nginx 服务的情况下平滑变更 Nginx 配置
修改 /usr/local/webserver/nginx/conf/nginx.conf 配置文件后,请执行以下命令检查配置文件是否正确:

service nginx test

如果屏幕显示以下两行信息,说明配置文件正确:
the configuration file /usr/local/webserver/nginx/conf/nginx.conf syntax is ok
the configuration file /usr/local/webserver/nginx/conf/nginx.conf was tested successfully

平滑变更 Nginx 配置

service nginx reload