2:负载均衡器绑定一个虚拟IP。用户通过虚拟IP访问应用,由负载均衡器进行代理。如果其中一个应用节点失效,Nginx会从负载均衡器中去掉,等到再次可用时,再加入其中。
3:如果负载均衡器1宕机,负载均衡器2接手工作,通过有一个后台作业,不停运行监测,如果载均衡器1不可到达。就给本机添加同一虚拟IP。这样用户访问就被负载均衡器2接手工作,用户使用不需换IP,同样如果负载均衡器2宕机,相同过程被负载均衡器1接手工作
4:如果有域名,可以使用两个VIP,DNS绑定这两个VIP,如果其中一个负载均衡失效,其vip添加到一台负载均衡所在的机子。等失效负载均衡恢复以后,再添加到本机。
5:该方案可以保证任何点,都有一个备份。保持高可用
测试主机:192.168.20.14 和 193.168.20.16
虚拟IP:192.168.20.23
主机环境:
linux 2.6.9-78.EL
apache-tomcat-6.0.26
jdk1.6.0_20
nginx-0.7.67
添加VIP
/sbin/ifconfig eth0:1 192.168.20.23 broadcast 192.168.20.255 netmask 255.255.255.0 up
切换VIP shell脚本:
主负载均衡运行脚本:nginx_master_ha.sh
#!/bin/sh LANG=C date=$(date -d "today" +"%Y-%m-%d %H:%M:%S") function_bind_vip() { /sbin/ifconfig eth0:1 192.168.20.23 broadcast 192.168.20.255 netmask 255.255.255.0 up } function_restart_nginx() { kill -USR1 `cat /usr/local/nginx/logs/nginx.pid` } function_remove_vip() { /sbin/ifconfig eth0:1 192.168.20.23 broadcast 192.168.20.255 netmask 255.255.255.0 down } bind_vip="N"; #主负载均衡。如果发现自己不可用,去掉绑定VIP,这时候备负载均衡会接管 while true do httpcode_local_rip=`/usr/bin/curl -o /dev/null -s -w %{http_code} http://192.168.20.15` if [ "x$httpcode_local_rip" == 'x200' ] then if [ "$bind_vip" == "N" ] then function_bind_vip function_restart_nginx bind_vip="Y" fi else if [ "$bind_vip" == "Y" ] then function_remove_vip bind_vip="N" fi fi sleep 5 done
备负载均衡运行脚本:nginx_slave_ha.sh
#!/bin/sh LANG=C date=$(date -d "today" +"%Y-%m-%d %H:%M:%S") function_bind_vip() { /sbin/ifconfig eth0:1 192.168.20.23 broadcast 192.168.20.255 netmask 255.255.255.0 up } function_restart_nginx() { kill -USR1 `cat /usr/local/nginx/logs/nginx.pid` } function_remove_vip() { /sbin/ifconfig eth0:1 192.168.20.23 broadcast 192.168.20.255 netmask 255.255.255.0 down } bind_vip="N"; #备负载均衡。如果发现主负载均衡不可用,由自己接管,当主负载均衡可用时,交由主负载均衡接管 while true do httpcode_remote_rip=`/usr/bin/curl -o /dev/null -s -w %{http_code} http://192.168.20.15` if [ "x$httpcode_remote_rip" != 'x200' ] then if [ "$bind_vip" == "N"] then function_bind_vip function_restart_nginx bind_vip="Y" fi else if [ "$bind_vip" == "Y" ] then function_remove_vip bind_vip="N" fi fi sleep 5 done
ngnix.conf配置:
#user nobody; worker_processes 2; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; worker_rlimit_nofile 1024; events { use epoll; worker_connections 1024; } http { include mime.types; default_type application/octet-stream; #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; sendfile on; tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; upstream backend { server 192.168.20.14:8080 weight=10; server 192.168.20.16:8080 weight=10; } server { listen 80; server_name 192.168.20.14; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.jsp index.html index.htm; 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; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }