1. 程式人生 > 其它 >負載均衡配置策略

負載均衡配置策略

前言

的目的是為了解決單個節點壓力過大,造成Web服務響應過慢,嚴重的情況下導致服務癱瘓,無法正常提供服務。春節期間在12306網站上買過火車票的朋友應該深有體會,有時查詢一張火車票都會很慢,甚至整個網頁都卡住不動了。通常一個訪問量非常大的Web網站(比如:淘寶、京東、12306等),由於一個Web服務同時能處理的使用者併發請求的數量有限,同時還有機器故障的情況,所以一個Web站點通常會在N臺機器上各部署一套同樣的程式。當某一個服務掛掉的時候,還有第二個、第三個、第N個服務。。。繼續為使用者提供服務,給使用者的感覺,你的服務還在正常的執行!在這些提供同樣服務的機器當中,在硬體配置方面也各不一樣,這樣就會存在部份機器效能非常好,能快速計算並響應使用者的請求,另外一部份機器可能配置差點,響應使用者的請求的時間會長一些。這就需要我們思考一個問題?如果有一個服務正在同時處理1000個使用者的請求,這個服務的上限可能最多能同時處理1000個使用者的請求,這時它已經很忙了,如果此時又有一個新請求過來,我們仍然把這個請求分配給這臺機器,這時候這個請求就只能在乾等著,等這個服務處理完那些請求後,再繼續處理它。這樣在瀏覽器中的反應就像12306我們在春節買票一樣,卡在那不動了,讓使用者眼巴巴的乾著急。而能提供同樣服務的其它機器,這時確很空閒。這樣不僅是對伺服器資源的浪費,也充分發揮不出弄多臺伺服器裝同一個服務的最高價值。我們通常稱對某一臺機器的訪問量稱為負載量,如何將一個使用者的請求,合理的分配到一臺能快速響應使用者請求的伺服器上,我們就需要用到一些負載策略。也就體現出了文章主題的用意了:負載均衡,將使用者的所有HTTP請求均衡的分配到每一臺機器上,充分發揮所有機器的效能,提高服務的質量和使用者體驗。負載均衡可以通過負載均衡網路硬體裝置和Web伺服器軟體來實現,前者裝置成本較高,小公司通常負擔不起,所以後者一般是我們的首選。實現負載均衡常用的Web伺服器軟體有Nginx、HAProxy、LVS、Apache,本文主要介紹Nginx的負載均衡策略,至於Nginx是幹嘛的,自行百度。這篇文章介紹了Nginx、HAProxy和LVS的優缺點。

一、內建負載策略

Nginx負載均衡是通過upstream模組來實現的,內建實現了三種負載策略,配置還是比較簡單的。官網負載均衡配置說明:http://nginx.org/en/docs/http/load_balancing.html

  • 輪循(預設)
    Nginx根據請求次數,將每個請求均勻分配到每臺伺服器

  • 最少連線
    將請求分配給連線數最少的伺服器。Nginx會統計哪些伺服器的連線數最少。

  • IP Hash
    繫結處理請求的伺服器。第一次請求時,根據該客戶端的IP算出一個HASH值,將請求分配到叢集中的某一臺伺服器上。後面該客戶端的所有請求,都將通過HASH演算法,找到之前處理這臺客戶端請求的伺服器,然後將請求交給它來處理。

  • url_hash(三方)

    按訪問url的hash結果來分配請求,使每個url定向到同一個後端伺服器,後端伺服器為快取時比較有效。

    1.7.2版本以後,url_hash模組已經整合到了nginx原始碼當中,不需要單獨安裝。

  • fair

    根據後端伺服器的響應時間來分配請求,響應時間短的優先分配。Nginx本身是不支援 fair 的,如果需要使用這種排程演算法,必須下載Nginx的 upstream_fair 模組。

  • least_conn

    請求被髮送到當前活躍連線最少的後端伺服器。會考慮weight的值。如果有多個後端伺服器的 conns 值同為最小的,那麼對它們採用加權輪詢演算法(weight)。

1、輪循

http {
# ... 省略其它配置

upstream tomcats {
    server 192.168.0.100:8080;
    server 192.168.0.101:8080;
    server example.com:8080;
}

server {
    listen 80;

    location / {
        proxy_pass http://tomcats;
    }
}

# ... 省略其它配置
}
  • proxy_pass http://tomcats:表示將所有請求轉發到tomcats伺服器組中配置的某一臺伺服器上。
  • upstream模組:配置反向代理伺服器組,Nginx會根據配置,將請求分發給組裡的某一臺伺服器。tomcats是伺服器組的名稱。
  • upstream模組下的server指令:配置處理請求的伺服器IP或域名,埠可選,不配置預設使用80埠。通過上面的配置,Nginx預設將請求依次分配給100,101,102來處理,可以通過修改下面這些引數來改變預設的分配策略:

2、weight(加權輪詢)

跟據配置的權重的大小而分發給不同伺服器不同數量的請求。如果不設定,則預設為1

upstream tomcats {
    server 192.168.0.100:8080 weight=2;  # 2/6次
    server 192.168.0.101:8080 weight=3;  # 3/6次
    server 192.168.0.102:8080 weight=1;  # 1/6次
}

上例配置,表示6次請求中,100分配2次,101分配3次,102分配1次

  • max_fails
    預設為1。某臺Server允許請求失敗的次數,超過最大次數後,在fail_timeout時間內,新的請求將不會分配給這臺機器。如果設定為0,Nginx會將這臺Server置為永久無效狀態,然後將請求發給定義了proxy_next_upstream, fastcgi_next_upstream, uwsgi_next_upstream, scgi_next_upstream, and memcached_next_upstream指令來處理這次錯誤的請求。

  • fail_timeout
    預設為10秒。某臺Server達到max_fails次失敗請求後,在fail_timeout期間內,nginx會認為這臺Server暫時不可用,不會將請求分配給它

    upstream tomcats {
        server 192.168.0.100:8080 weight=2 max_fails=3 fail_timeout=15;
        server 192.168.0.101:8080 weight=3;
        server 192.168.0.102:8080 weight=1;
    }
    

    192.168.0.100這臺機器,如果有3次請求失敗,nginx在15秒內,不會將新的請求分配給它。

  • backup
    備份機,所有伺服器掛了之後才會生效

    upstream tomcats {
        server 192.168.0.100:8080 weight=2 max_fails=3 fail_timeout=15;
        server 192.168.0.101:8080 weight=3;
        server 192.168.0.102:8080 backup;
    }
    

    在100和101都掛了之前,102為不可用狀態,不會將請求分配給它。只有當100和101都掛了,102才會被啟用。

  • down
    標識某一臺server不可用。可能能通過某些引數動態的啟用它吧,要不真沒啥用。

    upstream tomcats {
        server 192.168.0.100:8080 weight=2 max_fails=3 fail_timeout=15;
        server 192.168.0.101:8080 down;
        server 192.168.0.102:8080 backup;
    }
    表示101這臺Server為無效狀態,不會將請求分配給它。
    
  • max_conns
    限制分配給某臺Server處理的最大連線數量,超過這個數量,將不會分配新的連線給它。預設為0,表示不限制。注意:1.5.9之後的版本才有這個配置

    upstream tomcats {
        server 192.168.0.100:8080 max_conns=1000;
    }
    

    表示最多給100這臺Server分配1000個請求,如果這臺Server正在處理1000個請求,nginx將不會分配新的請求給到它。假如有一個請求處理完了,還剩下999個請求在處理,這時nginx也會將新的請求分配給它。

  • resolve
    將server指令配置的域名,指定域名解析伺服器。需要在http模組下配置resolver指令,指定域名解析服務

    http {
        resolver 10.0.0.1;
        upstream u {
            zone ...;
            ...
            server example.com resolve;
        }
    }
    

    表示example.com域名,由10.0.0.1伺服器來負責解析。
    upstream模組server指令的其它引數和詳細配置說明,請參考官方文件。

3、ip_hash

nginx會讓相同的客戶端ip請求相同的伺服器。

upstream mysvr { 
    server 127.0.0.1:7878; 
    server 192.168.10.121:3333;
    ip_hash;
}

注意:

ip_hash是容易理解的,但是因為僅僅能用ip這個因子來分配後端,因此ip_hash是有缺陷的,不能在一些情況下使用:

  • nginx不是最前端的伺服器。

    ip_hash要求nginx一定是最前端的伺服器,否則nginx得不到正確ip,就不能根據ip作hash。譬如使用的是squid為最前端,那麼nginx取ip時只能得到squid的伺服器ip地址,用這個地址來作分流是肯定錯亂的。

  • nginx的後端還有其它方式的負載均衡。

假如nginx後端又有其它負載均衡,將請求又通過另外的方式分流了,那麼某個客戶端的請求肯定不能定位到同一臺session應用伺服器上。這麼算起來,nginx後端只能直接指向應用伺服器,或者再搭一個squid,然後指向應用伺服器。最好的辦法是用 location作一次分流,將需要session的部分請求通過ip_hash分流,剩下的走其它後端去。

4、url_hash(第三方)

1.7.2版本以後,url_hash模組已經整合到了nginx原始碼當中,不需要單獨安裝。

例:在upstream中加入hash語句,server語句中不能寫入weight等其他的引數,hash_method是使用的hash演算法  

upstream resinserver{
    server 127.0.0.1:7878; 
    server 192.168.10.121:3333;
  	hash $request_uri;
  	hash_method crc32;
}

5、least_conn

請求被髮送到當前活躍連線最少的後端伺服器。會考慮weight的值。如果有多個後端伺服器的 conns 值同為最小的,那麼對它們採用加權輪詢演算法(weight)。

upstream api {
    least_conn;
    server 192.168.0.1:8081; 
    server 192.168.0.2:8081; 
}

6、fair

  • 根據伺服器的響應時間來分配請求,響應時間短的優先分配,即負載壓力小的優先會分配。

    由於fair模組是第三方提供的,所以在編譯nginx原始碼的時候,需要將fair新增到nginx模組中。

    假設我的nginx是通過原始碼安裝的,安裝在/opt/nginx目錄下,而且安裝時沒有新增fair模組
    下載fair模組原始碼
    下載地址:https://github.com/xyang0917/nginx-upstream-fair

    cd /opt
    wget https://github.com/xyang0917/nginx-upstream-fair/archive/master.zip
    unzip master.zip
    

    解壓後的目錄名為:nginx-upstream-fair-master

  • 重新編譯nginx,將fair模組新增到編譯引數
    我的nginx原始碼目錄在/opt/nginx-1.10.0

    cd /opt/nginx-nginx-1.10.0
    ./configure --prefix=/opt/nginx --add-module=/opt/nginx-upstream-fair-master
    make
    

    注意:不要執行make install,這樣會覆蓋之前nginx的配置

  • 將新編譯的nginx可執行程式拷貝到/opt/nginx/sbin/目錄下,覆蓋之前安裝的nginx
    編譯後的nginx執行程式,放在ngin x原始碼的objs目錄下

    ps -aux | grep nginx
    kill -9 nginx程序ID  # 停止nginx服務
    cp /opt/nginx-1.10.0/objs/nginx /opt/nginx/sbin/  # 覆蓋舊的nginx
    nginx # 啟動服務
    
  • 配置使用fair負載策略模組:

    upstream tomcats {
        fair;
        server 192.168.0.100:8080;
        server 192.168.0.101:8080;
        server 192.168.0.102:8080;
    }
    

    由於採用fair負載策略,配置weigth引數改變負載權重將無效。