在家上51cto时随意点了一个连接,然后看到“拯救赵明”的帖子,发现赵明此时公司的网络拓扑图中存在很多
问题:

1、负责均衡器存在单点故障
2、缺少收集日志系统
3、缺少专业的IPS系统
4、数据库没有主从之分,不存在负载
5、缺少Webserver健康检查系统

经分析调整后的架构图如下:


此架构说明:
1、使用两台nginx实现负载均衡器,解决了单点故障、高并发问题,
2、数据库采用负载均衡,通过开发语言调用memcached缓存数据,从而大大降低了数据库的压力
3、增加了一台多功能服务器,作用:
   (1)、用来检查Webserver服务器的80状态和首页的状态
   (2)、用来存放Webserver的数据文件,Webserver的网页文件是多功能服务器通过推送方式
        传到两台Webserver服务器相同目录下的,推送方式用的是开源软件rsync+intify,可
        以实时同步两地数据,从而保证了原始数据的安全性;
   (3)、用来存放各个系统的日志信息,监控故障通知功能

一、使用两台nginx做负载均衡服务器
    本来一开始是考虑用lvs+keepalived做负载均衡,可是一想它现在有很多缺点不能跟nginx
    相比,选用nginx的原因有以下几点:
 
1、支持高并发连接:经官方测试可以跑到5w并发,在生产环境可以跑2w~3w的并发连接数
2、内存消耗少:nginx+PHP(fastcgi)服务在3w并发的连接下,开始10个nginx进程消耗150MB内
   存(15MB×10),开启64个php-fgi的进程消耗1280MB内存(20MB×64),加上系统自身消耗的内存,
   总共消耗不到2GB。
3、成本低廉:nginx是遵循BSD开源协议,是一款免费开源的软件。
4、其他理由:
   (1)、配置文件非常简单易懂
   (2)、支持rewrite重写规则
   (3)、内置了健康检查功能
   (4)、支持GZIP压缩,可以大大节省带宽资源
   (5)、稳定性高
   (6)、支持热部署,重启服务不需要中断服务
   (7)、高版本支持缓存功能,加上第三方的模块,可以像squid一样清除指定的url缓存

用两台nginx服务器做负载均衡,两台同时在线运行接受外部用户的访问,而不是一台运行另一台处于
空闲状态,两台服务器的故障切换通过脚本切换。此种方案已经有人(张宴)用在生产环境中测试了,说
很稳定,现在写出来和大家一起分享一下。

此脚本出自张宴之手,在此引用:
每台负载均衡器各自绑定一个公网虚拟vip,

负载均衡器1vip:61.1.1.2
负载均衡器2vip:61.1.1.3
负载均衡器1真实ip:61.1.1.4
负载均衡器1真实ip:61.1.1.5
IDC公网网关:61.1.1.1

服务器1
/sbin/ifconfig eth0:1 61.1.1.2 broadcast 61.1.1.255 netmask 255.255.255.0 up
/sbin/route add -host 61.1.1.2 dev eth0:1
/sbin/arping -I eth0 -c 3 -s 61.1.1.2 61.1.1.1

服务器2
/sbin/ifconfig eth0:1 61.1.1.3 broadcast 61.1.1.255 netmask 255.255.255.0 up
/sbin/route add -host 61.1.1.3 dev eth0:1
/sbin/arping -I eth0 -c 3 -s 61.1.1.3 61.1.1.1

两个shell脚本 来实现自动故障转移

nginx_ha1.sh,放在nginx负载均衡器1上:
#!/bin/bash
LANG=C
date=$(date -d "today" + "%Y-%m-%d %H:%M:%S")

function_bind_vip1()
{
    /sbin/ifconfig eth0:ha1 61.1.1.2 broadcast 219.232.254.255 netmask 255.255.255.192 up
    /sbin/route add -host 61.1.1.2  dev eth0:ha1
}

function_bind_vip2()
{
    /sbin/ifconfig eth0:ha2 61.1.1.3 broadcast 219.232.254.255 netmask 255.255.255.192 up
    /sbin/route add -host 61.1.1.3  dev eth0:ha2
}

function_restart_nginx()
{
    kill -USR1 `cat /usr/local/webserver/nginx/nginx.pid`
}

function_remove_vip1()
{
    /sbin/ifconfig eth0:ha1 61.1.1.2 broadcast 219.232.254.255 netmask 255.255.255.192 down
}

function_remove_vip2()
{
    /sbin/ifconfig eth0:ha2 61.1.1.3 broadcast 219.232.254.255 netmask 255.255.255.192 down
}

function_vip_arping1()
{
    /sbin/arping -I eth0 -c 3 -s 61.1.1.2 61.1.1.1 > /dev/null 2>&1
}

function_vip_arping2()
{
    /sbin/arping -I eth0 -c 3 -s 61.1.1.3 61.1.1.1 > /dev/null 2>&1
}

bind_time_vip1="N";
bind_time_vip2="N";

while true
do
    httpcode_rip1=`/usr/bin/curl -o /dev/null -s -w %{http_code} http://61.1.1.4`
    httpcode_rip2=`/usr/bin/curl -o /dev/null -s -w %{http_code} http://61.1.1.5`
    if [ x$httpcode_rip1 == "x200" ];
    then
        if [ $bind_time_vip1 == "N" ];
        then
        function_bind_vip1
        function_vip_arping1
        function_restart_nginx
        bind_time_vip1="Y"
        fi
        function_vip_arping1
    else
        if [ $bind_time_vip1 == "Y" ];
        then
        function_remove_vip1
        bind_time_vip1="N"
        fi
    fi
    if [ x$httpcode_rip2 == "x200" ];
    then
        if [ $bind_time_rip2 == "Y" ];
        then
        function_remove_vip2
        bind_time_vip2="N"
        fi

    else
        if [ $bind_time_vip2 == "N" ];
        then
        function_bind_vip2
        function_vip_arping2
        function_restart_nginx
        bind_time_vip2="Y"
        fi
        function_vip_arping2
    fi
    sleep 5
done
在nginx负载均衡器1将脚本驻留后台运行:
nohup /bin/bash ./nginx_ha1.sh 2>&1 > /dev/null &

服务器2脚本 nginx_ha2.sh,部署在nginx负载均衡器上:

#!/bin/bash
LANG=C
date=$(date -d "today" + "%Y-%m-%d %H:%M:%S")

function_bind_vip1()
{
    /sbin/ifconfig eth0:ha1 61.1.1.3 broadcast 219.232.254.255 netmask 255.255.255.192 up
    /sbin/route add -host 61.1.1.3  dev eth0:ha1
}

function_bind_vip2()
{
    /sbin/ifconfig eth0:ha2 61.1.1.2 broadcast 219.232.254.255 netmask 255.255.255.192 up
    /sbin/route add -host 61.1.1.2  dev eth0:ha2
}

function_restart_nginx()
{
    kill -USR1 `cat /usr/local/webserver/nginx/nginx.pid`
}

function_remove_vip1()
{
    /sbin/ifconfig eth0:ha1 61.1.1.3 broadcast 219.232.254.255 netmask 255.255.255.192 down
}

function_remove_vip2()
{
    /sbin/ifconfig eth0:ha2 61.1.1.2 broadcast 219.232.254.255 netmask 255.255.255.192 down
}

function_vip_arping1()
{
    /sbin/arping -I eth0 -c 3 -s 61.1.1.3 61.1.1.1 > /dev/null 2>&1
}

function_vip_arping2()
{
    /sbin/arping -I eth0 -c 3 -s 61.1.1.2 61.1.1.1 > /dev/null 2>&1
}

bind_time_vip1="N";
bind_time_vip2="N";

while true
do
    httpcode_rip1=`/usr/bin/curl -o /dev/null -s -w %{http_code} http://61.1.1.5`
    httpcode_rip2=`/usr/bin/curl -o /dev/null -s -w %{http_code} http://61.1.1.4`
    if [ x$httpcode_rip1 == "x200" ];
    then
        if [ $bind_time_vip1 == "N" ];
        then
        function_bind_vip1
        function_vip_arping1
        function_restart_nginx
        bind_time_vip1="Y"
        fi
        function_vip_arping1
    else
        if [ $bind_time_vip1 == "Y" ];
        then
        function_remove_vip1
        bind_time_vip1="N"
        fi
    fi
    if [ x$httpcode_rip2 == "x200" ];
    then
        if [ $bind_time_rip2 == "Y" ];
        then
        function_remove_vip2
        bind_time_vip2="N"
        fi

    else
        if [ $bind_time_vip2 == "N" ];
        then
        function_bind_vip2
        function_vip_arping2
        function_restart_nginx
        bind_time_vip2="Y"
        fi
        function_vip_arping2
    fi
    sleep 5
done

在nginx负载均衡器2将脚本驻留后台运行:
nohup /bin/bash ./nginx_ha2.sh 2>&1 > /dev/null &


关于web服务器用nginx而不用apache,请google一下就知道了,这里就掠过了。

nginx负载均衡的配置请参考张宴的博客:http://blog.s135.com/post/306/

mysql负载均衡的配置请参考张宴的博客:http://blog.s135.com/post/379/ 和守住每一天的博客
http://liuyu.blog.51cto.com/183345/305145

关于多功能服务器所需的脚本,还在编写测试中,等测试没有问题了会贴出来与大家一起分享

【拯救赵明】安全方案:http://liuyu.blog.51cto.com/183345/305145 守住每一天 写的已经很不错了
它所用的软件都是开源软件。这样可以为企业可以节省很大的成本。我写出来只是想在它的基础上再加点
自己的见解。

热爱技术,热爱开源软件。

可能在写的过程中,有些地方叙述错误,请看的同仁指出来。在这感谢张宴,感谢守住每一天,谢谢!

分享技术快乐自我