Nginx雙機高可用

nginx負載均衡服務器的雙機高可用

如果將web服務器集羣當作一個城池,那麼負載均衡服務器則相當於城門,重要性不言而喻。如果“城門”關了,與外界的通道也就斷了,如果只要一臺均衡服務器,當該服務器發生故障時,則會導致整個網站無法訪問。因此我們需要來兩臺以上的服務器,實現故障轉移與高可用。
雙機高可用一般是通過虛擬IP(飄移IP)方法來實現的,基於linux/unix的IP別名技術。雙機高可用方法目前分爲兩種:

(1):一臺服務器加一臺熱被備務器,正常情況下,主服務器綁定一個公網虛擬IP,提供負載均衡服務,熱備服務器處於空閒狀態,當主服務器發生故障時,熱備服務器接管主服務器的公網虛擬IP,提供負載均衡服務;
(2):兩臺負載均衡服務器都處於活動狀態,各自綁定一個公網虛擬IP,提供負載均衡服務,當其中一臺發生故障時,另一臺接管發生故障服務器的公網虛擬IP。

第一種方式:
(1)www.yourdomin.com域名解析到虛擬IP 61.1.1.2
(2)正常情況下,主機61.1.1.4綁定虛擬IP 61.1.1.2

/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 61.1.1.2 61.1.1.1

(3):用戶訪問:www.yourdomin.com(虛擬IP: 61.1.1.2)實際訪問的是主機61.1.1.4,而備用機 61.1.1.5 則處於空閒狀態。
(4):如果主機61.1.1.4發生故障,背機61.1.1.5將在幾秒鐘內接管虛擬IP61.1.1.2,與自己綁定,併發送APping的公網網關刷新MAC地址。

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

(5):這時,用戶訪問www.yourdomin.com(虛擬IP)實際上訪問的是備機 61.1.1.1,從而實現故障轉移與高可用,避免了單點故障。

另外,第一種方式可以利用基於VRRP路由協議的Keeoalive軟件實現的。

第二種方式:
(1):www.yourdomin.com 域名通過DNS輪詢解析到虛擬IP 61.1.1.2和61.1.1.3上。
(2)正常情況下,服務器個綁定一個虛擬IP。
在服務器161.1.1.4上執行以下命令
/sbin/ifconfig etho:1 61.1.1.2 broadcast 61.1.1.255 netmask 255.255.255.0 up
/sbin/ifconfig add -host 61.1.1.2 dev eth0:1
/sbin/arping -I etho -c 3 -s 61.1.1.2 61.1.1.1
在服務器161.1.1.5上執行以下命令
/sbin/ifconfig etho:1 61.1.1.3 broadcast 61.1.1.255 netmask 255.255.255.0 up
/sbin/ifconfig add -host 61.1.1.2 dev eth0:1
/sbin/arping -I etho -c 3 -s 61.1.1.3 61.1.1.1
(3):用戶訪問www,yourdomin.com (虛擬IP 61.1.1.2和61.1.1.3)實際上是根據DNS輪詢訪問兩臺負載均衡服務器,兩臺服務器均處於活躍狀態。
(4):如果服務器1發生故障,服務器2將在幾秒鐘內接管服務器1的虛擬IP 61.1.1.2,與自己已綁定,併發送ARPing包給IDC的公關網關刷新新的MAC地址。
在服務器2上執行以下命令:
/sbin/ifconfig etho:1 61.1.1.2 broadcast 61.1.1.255 netmask 255.255.255.0 up
/sbin/ifconfig add -host 61.1.1.2 dev eth0:1
/sbin/arping -I etho -c 3 -s 61.1.1.2 61.1.1.1

我們可以寫兩個腳本,來實現第二種方式的自動故障轉移。

以下是部署在Nginx負載均衡服務器1的腳本:

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

function_bind_vip1()
{
    /sbin/ifconfig etho: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:hal
}
function_bind_vip2()
{

    /sbin/ifconfig etho:ha2 61.1.1.3 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 etho:ha1 61.1.1.2 broadcast 219.232.254.255 netamsk 255.255.255.192 down
}

function_remove_vip2()
{
    /sbin/ifconfig etho:ha2 61.1.1.3 broadcast 219.232.254.255 netamsk 255.255.255.192 down
}
function_vip_arping1()
{
    /sbin/ifconfig -I eth0 -c 3 -e 611..1.1.2 61.1.1.1 > /dev/null 2>&1
}
function_vip_arping2()
{
    /sbin/ifconfig -I eth0 -c 3 -e 611..1.1.3 61.1.1.1 > /dev/null 2>&1
}

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

while true
do
    httpcode_arp1='/usr/bin/cur1 -o /dev/null s -w %{http_code} http://61.1.1.4'
    httpcode_arp2='/usr/bin/cur1 -o /dev/null s -w %{http_code} http://61.1.1.5'

    if [x$httpcode_rip1 == "x200"];
    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_remote_vip1
            bind_time_vip="N"
        fi
    fi

    if [x$httpcode_arp2 == "x200"];
    then
        if[ $bind_time_vip2 == "Y"]
        then
            function_rempve_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/sh ./nginx_hal.sh 2>&1 > dev/null &

以下代碼部署在服務器2:

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

function_bind_vip1()
{
    /sbin/ifconfig etho: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:hal
}
function_bind_vip2()
{

    /sbin/ifconfig etho: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 etho:ha1 61.1.1.3 broadcast 219.232.254.255 netamsk 255.255.255.192 down
}

function_remove_vip2()
{
    /sbin/ifconfig etho:ha2 61.1.1.2 broadcast 219.232.254.255 netamsk 255.255.255.192 down
}
function_vip_arping1()
{
    /sbin/ifconfig -I eth0 -c 3 -e 61.1.1.3  61.1.1.1 > /dev/null 2>&1
}
function_vip_arping2()
{
    /sbin/ifconfig -I eth0 -c 3 -e 61.1.1.2  61.1.1.1 > /dev/null 2>&1
}

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

while true
do
    httpcode_arp1='/usr/bin/cur1 -o /dev/null s -w %{http_code} http://61.1.1.5'
    httpcode_arp2='/usr/bin/cur1 -o /dev/null s -w %{http_code} http://61.1.1.4'

    if [x$httpcode_rip1 == "x200"];
    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_remote_vip1
            bind_time_vip="N"
        fi
    fi

    if [x$httpcode_arp2 == "x200"];
    then
        if[ $bind_time_vip2 == "Y"]
        then
            function_rempve_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/sh ./nginx_ha2.sh 2>&1 > dev/null &

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章