Nginx+Keepalived实现负载均衡高可用的WEB服务集群,nginx作为负载均衡器,keepalived作为高可用,当其中的一台负载均衡器(nginx)发生故障时可以迅速切换到备用的负载均衡器(nginx),保持业务的连续性。
1、服务器的环境配置及IP分配
操作系统:CentOS release 6.7 (Final)
nginx版本:nginx/1.8.0
keepalived版本:Keepalived v1.2.13
Nginx + keepalived服务器的IP分配表
服务器名称 IP 作用
DR1 192.168.171.10 提供负载均衡
DR2 192.168.171.20 提供负载均衡
192.168.171.100 网站的VIP地址
RS1 192.168.171.30 提供web服务
RS2 192.168.171.40 提供web服务
2、分别在DR1和DR2上安装Nginx负载均衡器和相关的脚本
1)、添加运行nginxd的用户组www及nginx存放日志的位置,并且安装gcc的基础库(使用yum安装)
yum install -y make apr* autoconf automakecurl curl-devel gcc gcc-c++ \ gtk+-devel zlib-devel openssl openssl-develpcre-devel gd kernel keyutils \patch perl kernel-headers compat* cpp glibc libgomp libstdc++-develkeyutils-libs-devel \libsepol-devel libselinux-devel krb5-devel libXpm* freetype freetype-devel freetype*fontconfig \fontconfig-devel libjpeg*libpng* php-common php-gd gettext gettext-devel ncurses* libtool* \libxml2libxml2-devel patch policycoreutils bison pcre pece-devel
创建存放web数据目录
groupadd www #创建组groupadd –g www www #创建www用户并加入www组mkdir –p /data/logs/ #存放日志的目录chown R www.www /data/logs/ #修改所有者和所属组
2)、下载并安装ngixn-1.8.0,默认下载到/usr/local/src/目录下
cd /usr/local/srcwget http://nginx.org/download/nginx-1.8.0.tar.gz #下载nginxtar zxvf nginx-1.8.0.tar.gzcd nginx-1.8.0 ./configure --prefix=/usr/local/nginx--with-http_realip_module --with-http_sub_module \ --with-http_gzip_static_module--with-http_stub_status_module --with-pcre --with-http_ssl_modulemake && make install
3)、配置nginx,默认的配置文件是在 /usr/local/nginx/conf/nginx.conf
vim /usr/local/nginx/conf/nginx.conf
user www www; #使用的用户worker_processes 2;error_log/usr/local/nginx/logs/nginx_error.log crit;pid /usr/local/nginx/logs/nginx.pid;worker_rlimit_nofile 51200; events{ use epoll; worker_connections 6000;} http{ include mime.types; default_type application/octet-stream; server_names_hash_bucket_size 3526; server_names_hash_max_size 4096; log_format combined_realip '$remote_addr $http_x_forwarded_for[$time_local]' '$host "$request_uri" $status' '"$http_referer" "$http_user_agent"'; #日志的格式 sendfile on; tcp_nopush on; keepalive_timeout 30; client_header_timeout 3m; client_body_timeout 3m; send_timeout 3m; connection_pool_size 256; client_header_buffer_size 1k; large_client_header_buffers 8 4k; request_pool_size 4k; output_buffers 4 32k; postpone_output 1460; client_max_body_size 10m; client_body_buffer_size 256k; client_body_temp_path /usr/local/nginx/client_body_temp; proxy_temp_path /usr/local/nginx/proxy_temp; fastcgi_temp_path /usr/local/nginx/fastcgi_temp; fastcgi_intercept_errors on; tcp_nodelay on; gzip on; gzip_min_length 1k; gzip_buffers 4 8k; gzip_comp_level 5; gzip_http_version 1.1; gzip_types text/plain application/x-javascript text/css text/htmapplication/xml; #定义负载均衡的配置模块upstream myserver { ip_hash; #测试的时候建议注释掉 server 192.168.171.30:80 weight=1 max_fails=3 fail_timeout=20s; server 192.168.171.40:80 weight=1 max_fails=3 fail_timeout=20s; }server { listen 80; server_name www.balichlb.org ; index index.htm index.html; location / { proxy_pass http://myserver; proxy_set_header Host $Host; proxy_next_upstream errortimeout http_500 http_502 http_504; proxy_read_timeout 10s; proxy_set_header X-Real-IP$remote_addr; proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for; } access_log/data/lgos/access.log combined_realip; #访问的日志 } }
分别在两台nginx(DR1和DR2)执行:/usr/local/nginx/sbin/nginx 命令启动nginx服务,然后使用 lsof –i:80 命令检查(当然可以可以编写nginx的启动脚本)
vim /etc/init.d/nginx #编写nginx启动、关闭、脚本
#!/bin/bash# chkconfig: - 30 21# description: http service.# Source Function Library. /etc/init.d/functions# Nginx Settings NGINX_SBIN="/usr/local/nginx/sbin/nginx"NGINX_CONF="/usr/local/nginx/conf/nginx.conf"NGINX_PID="/usr/local/nginx/logs/nginx.pid"RETVAL=0prog="Nginx" start() { echo -n $"Starting $prog: " mkdir -p /dev/shm/nginx_temp daemon $NGINX_SBIN -c $NGINX_CONF RETVAL=$? echo return $RETVAL} stop() { echo -n $"Stopping $prog: " killproc -p $NGINX_PID $NGINX_SBIN -TERM rm -rf /dev/shm/nginx_temp RETVAL=$? echo return $RETVAL} reload(){ echo -n $"Reloading $prog: " killproc -p $NGINX_PID $NGINX_SBIN -HUP RETVAL=$? echo return $RETVAL} restart(){ stop start} configtest(){ $NGINX_SBIN -c $NGINX_CONF -t return 0} case "$1" in start) start ;; stop) stop ;; reload) reload ;; restart) restart ;; configtest) configtest ;; *) echo $"Usage: $0{start|stop|reload|restart|configtest}" RETVAL=1esac exit $RETVAL
保存退出,修改启动脚本权限
chmod 755 /etc/init.d/nginx #修改权限chkconfig --add nginx #增加系统服务列表/etc/init.d/nginx start #启动nginx服务
3、安装keepalived,让其作为web和nginx的HA(高可用)
yum install -y keepalived
1)、分别配置在主和备nginx上的keepalived的配置文件,默认在/etc/keepalived/keepalived.conf
先在主nginx上配置:
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived#全局定义部分global_defs { notification_email { balich@foxmail.com } notification_email_from balich@foxmail.com smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id LVS_DEVEL} vrrp_instance VI_1 { state MASTER #主服务器是MASTER,备用服务器是BACKUP interface eth0 virtual_router_id 51 mcast_src_ip 192.168.171.10 #主nginx服务的ip地址 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.171.100 #设置虚拟IP地址,可以多个,一行一个 }}
在备用的服务器行的配置也基本相同,需要修改的地方如下:
state MASTER >> state BACKUPpriority 100 >> priority 99 #修改为小于主服务器上的mcast_src_ip 192.168.171.10 >>mcast_src_ip 192.168.171.20 #备用ngixn的ip
分别在两台负载均衡器上启动keepalived服务(先主后从)
/etc/init.d/keepalived start
可以通过日志信息查看keepalived的启动,此时在主nginx会有一个VIP绑定到eth0:0上。
现在的nginx确实可以对后端的web服务实现负载均衡了,但是如果nginx服务出现了故障,keepalived服务还在运行,无法把vip转移到备用的服务器上。可以使用如下脚本实现:
vim /etc/keepalived/nginx_pid.sh
#!/bin/bashwhile :do nginxpid=`ps-C nginx --no-header |wc -l` if[ $nginxpid -eq 0 ];then /etc/init.d/nginxstart sleep 3 if[ $nginxpid -eq 0];then /etc/init.d/keepalivedstop fifisleep 5done
将其放在后台上运行:
nohup /bin/bash /etc/keepalived/nginx_pid.sh &
4、模拟故障
1)、关闭主nginx的服务,测试脚本是否可以让正常运行。之间关闭keepalived服务,切换是否正常。
2)、主nginx服务修复后,重启在次启动keepalived服务后,能否重新接管服务。
3)、直接断开网络,查看服务。