負載均衡配置策略
前言
的目的是為了解決單個節點壓力過大,造成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-faircd /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.0cd /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引數改變負載權重將無效。