負(fù)載均衡目的:
將前端超高并發(fā)訪問轉(zhuǎn)發(fā)至后端多臺(tái)服務(wù)器進(jìn)行處理,解決單個(gè)節(jié)點(diǎn)壓力過大,造成Web服務(wù)響應(yīng)過慢,嚴(yán)重的情況下導(dǎo)致服務(wù)癱瘓,無法正常提供服務(wù)的問題。
工作原理:
負(fù)載均衡分為四層負(fù)載均衡和七層負(fù)載均衡。
四層負(fù)載均衡是工作在七層協(xié)議的第四層-傳輸層,主要工作是轉(zhuǎn)發(fā)。
它在接收到客戶端的流量以后通過修改數(shù)據(jù)包的地址信息(目標(biāo)地址和端口)將流量轉(zhuǎn)發(fā)到應(yīng)用服務(wù)器。
七層負(fù)載均衡是工作在七層協(xié)議的第七層-應(yīng)用層,主要工作是代理。
它首先會(huì)與客戶端建立一條完整的連接并將應(yīng)用層的請(qǐng)求流量解析出來,再按照調(diào)度算法選擇一個(gè)應(yīng)用服務(wù)器,并與應(yīng)用服務(wù)器建立另外一條連接將請(qǐng)求發(fā)送過去。
實(shí)例:
前端服務(wù)器:192.168.1.6
后端服務(wù)器1:192.168.1.5
后端服務(wù)器2:192.168.1.7
這里后端服務(wù)器也可以通過配置虛擬主機(jī)實(shí)現(xiàn)。
配置:
前端服務(wù)器主要配置upstream和proxy_pass:
upstream 主要是配置均衡池和調(diào)度方法。
proxy_pass 主要是配置代理服務(wù)器ip或服務(wù)器組的名字
proxy_set_header 主要是配置轉(zhuǎn)發(fā)給后端服務(wù)器的Host和前端客戶端真實(shí)ip。
#在http指令塊下配置upstream指令塊
upstream web {
server 192.168.1.5;
server 192.168.1.7;
}
#在location指令塊配置proxy_pass
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web;
proxy_next_upstream error http_404 http_502;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# proxy_next_upstream error http_404 http_502;
通過這個(gè)指令,可以處理當(dāng)后端服務(wù)返回404等報(bào)錯(cuò)時(shí),
直接將請(qǐng)求轉(zhuǎn)發(fā)給其他服務(wù)器,而不是把報(bào)錯(cuò)信息返回客戶端。
# proxy_set_header Host $host;
通過這個(gè)指令,把客戶端請(qǐng)求的host,轉(zhuǎn)發(fā)給后端,
否則,后端接收到的請(qǐng)求頭Host會(huì)是web,可能會(huì)導(dǎo)致報(bào)錯(cuò)誤的請(qǐng)求頭。
# proxy_set_header X-Real-IP $remote_addr
通過這個(gè)指令,把客戶端的IP轉(zhuǎn)發(fā)給后端服務(wù)器,在后端服務(wù)器的日志格式中,
添加$http_x_real_ip即可獲取原始客戶端的IP了。
均衡方式:
1. 輪詢
upstream web {
server 192.168.1.5;
server 192.168.1.7;
}
訪問前端IP:
[root@192 ~]# while true;do curl 192.168.1.6;sleep 2;done
this is 1.5 page
this is 1.7 page
this is 1.5 page
this is 1.7 page
#可以看到后端服務(wù)器,非常平均的處理請(qǐng)求。
2. 輪詢加權(quán)重
upstream web {
server 192.168.1.5 weight=3;
server 192.168.1.7 weight=1;
}
訪問前端IP:
[root@192 ~]# while true;do curl 192.168.1.6;sleep 1;done
this is 1.5 page
this is 1.5 page
this is 1.5 page
this is 1.7 page
this is 1.5 page
this is 1.5 page
this is 1.5 page
this is 1.7 page
#后端服務(wù),根據(jù)權(quán)重比例處理請(qǐng)求,適用于服務(wù)器性能不均的環(huán)境。
3. 輪詢+權(quán)重+最大連接錯(cuò)誤次數(shù)
錯(cuò)誤的連接由proxy_next_upstream, fastcgi_next_upstream等指令決定,且默認(rèn)情況下,后端某臺(tái)服務(wù)器出現(xiàn)故障了,nginx會(huì)自動(dòng)將請(qǐng)求再次轉(zhuǎn)發(fā)給其他正常的服務(wù)器(因?yàn)槟J(rèn) proxy_next_upstream=error timeout)。
所以即使我們沒有配這個(gè)參數(shù),nginx也可以幫我們處理error和timeout的相應(yīng),但是沒法處理404等報(bào)錯(cuò)。
為了看清楚本質(zhì),我們先將proxy_next_upstream設(shè)置為off,也就是不將失敗的請(qǐng)求轉(zhuǎn)發(fā)給其他正常服務(wù)器,這樣我們可以看到請(qǐng)求失敗的結(jié)果。
upstream web {
server 192.168.1.5 weight=1 max_fails=3 fail_timeout=9s;
#先將1.5這臺(tái)nginx關(guān)了。
server 192.168.1.7 weight=1;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web;
#proxy_next_upstream error http_404 http_502;
proxy_next_upstream off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# 在這里,我們將超時(shí)時(shí)間設(shè)置為9s,最多嘗試3次,
這里要注意,嘗試3次,依然遵循輪詢的規(guī)則,并不是一個(gè)請(qǐng)求,連接3次,
而是輪詢?nèi)?,?次處理請(qǐng)求的機(jī)會(huì)。
訪問前端IP:
[root@192 ~]# while true;do curl -I 192.168.1.6 2>/dev/null|grep HTTP/1.1 ;sleep 3;done
HTTP/1.1 502 Bad Gateway
HTTP/1.1 200 OK
HTTP/1.1 502 Bad Gateway
HTTP/1.1 200 OK
HTTP/1.1 502 Bad Gateway
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 502 Bad Gateway
# 我們?cè)O(shè)置的超時(shí)時(shí)間為9s,我們是每3s請(qǐng)求一次。
我們可以看到后端一臺(tái)服務(wù)器掛了后,請(qǐng)求沒有直接轉(zhuǎn)發(fā)給正常的服務(wù)器,
而是直接返回了502。嘗試三次后,等待9s,才開始再次嘗試(最后一個(gè)502)。
#要注意,第二行的200響應(yīng),并不是客戶端第一次的請(qǐng)求的響應(yīng)碼,而是客戶端第二次新的請(qǐng)求。
把proxy_next_upstream開啟,再來訪問看結(jié)果:
upstream web {
server 192.168.1.5 weight=1 max_fails=3 fail_timeout=9s;
#先將1.5這臺(tái)nginx關(guān)了。
server 192.168.1.7 weight=1;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web;
proxy_next_upstream error http_404 http_502;
#proxy_next_upstream off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
訪問前端IP:
[root@192 ~]# while true;do curl -I 192.168.1.6 2>/dev/null|grep HTTP/1.1 ;sleep 3;done
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
#可以看到現(xiàn)在沒有502報(bào)錯(cuò),請(qǐng)求都處理了。因?yàn)殄e(cuò)誤的響應(yīng)碼被proxy_next_upstream 獲取,這次請(qǐng)求被轉(zhuǎn)發(fā)給下一個(gè)正常的服務(wù)器了。
所以看到都是200,但是你應(yīng)該清楚,哪個(gè)200是響應(yīng)的上個(gè)服務(wù)器沒有處理請(qǐng)求,哪個(gè)200是正常的響應(yīng)。
4. ip_hash
upstream web {
ip_hash;
server 192.168.1.5 weight=1 max_fails=3 fail_timeout=9s;
server 192.168.1.7 weight=1;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web;
proxy_next_upstream error http_404 http_502;
#proxy_next_upstream off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
訪問前端IP:
[root@192 ~]# while true;do curl 192.168.1.6;sleep 2;done
this is 1.5 page
this is 1.5 page
this is 1.5 page
^C
[root@192 ~]# curl 192.168.1.7
this is 1.7 page
#可以看到1.7的服務(wù)是正常的,但是卻不轉(zhuǎn)發(fā)給1.7了,請(qǐng)求固定在了1.5的服務(wù)器上。
在使用負(fù)載均衡的時(shí)候會(huì)遇到會(huì)話保持的問題,常用的方法有:
a、ip hash,根據(jù)客戶端的IP,將請(qǐng)求分配到不同的服務(wù)器上;
b、cookie,服務(wù)器給客戶端下發(fā)一個(gè)cookie,具有特定cookie的請(qǐng)求會(huì)分配給它的發(fā)布者。
注意:cookie需要瀏覽器支持,且有時(shí)候會(huì)泄露數(shù)據(jù)。
先說到這,后面在結(jié)合業(yè)務(wù)細(xì)聊。
這將是nginx系列文章,可關(guān)注同名微信公眾號(hào):笨辦法學(xué)linux
獲取最近文章更新及精品軟件,軟件持續(xù)更新中。
