.說明
常見的集群架構(gòu)及相關(guān)軟件,可以參考下面的導(dǎo)圖:
互聯(lián)網(wǎng)企業(yè)常用的是負(fù)載均衡集群和高可用性集群,負(fù)載均衡集群強(qiáng)調(diào)“分擔(dān)”,通過一定的調(diào)度算法 ,可以實(shí)現(xiàn)用多個(gè)節(jié)點(diǎn)服務(wù)器來分擔(dān)用戶的訪問請(qǐng)求和數(shù)據(jù)流量;高可用性集群強(qiáng)調(diào)“高可用”,即一個(gè)節(jié)點(diǎn)失效了,它的任務(wù)可以立刻轉(zhuǎn)移到另一個(gè)備份的節(jié)點(diǎn)上(即一般通過設(shè)置主備來實(shí)現(xiàn))。顯然因?yàn)樨?fù)載均衡集群使用多個(gè)節(jié)點(diǎn)來分擔(dān)服務(wù),即使其中一個(gè)節(jié)點(diǎn)失效了,其它節(jié)點(diǎn)也可以繼續(xù)工作,因此它也具有高可用性。
下面介紹的是Nginx負(fù)載均衡的配置,同時(shí)也給出了實(shí)驗(yàn)環(huán)境。
1.實(shí)驗(yàn)環(huán)境說明
本次實(shí)驗(yàn)的測(cè)試環(huán)境使用的宿主機(jī)操作系統(tǒng)為Windows 7,在Vmware虛擬機(jī)安裝CentOS 6.5(3臺(tái)),說明如下:
| 主機(jī)類型 | 操作系統(tǒng) | IP地址 | 作用 |
|---|---|---|---|
| 宿主機(jī) | Windows 7 | 10.0.0.1/24(VMnet8的IP地址) | 遠(yuǎn)程3臺(tái)虛擬機(jī),進(jìn)行配置,同時(shí)也作為后面測(cè)試使用的客戶端 |
| 虛擬機(jī)1: lb01 | CentOS 6.5 | 10.0.0.7/24 | 負(fù)載均衡服務(wù)器lb01,將請(qǐng)求分擔(dān)到Web節(jié)點(diǎn)服務(wù)器中 |
| 虛擬機(jī)2: web01 | CentOS 6.5 | 10.0.0.9/24 | Web節(jié)點(diǎn)服務(wù)器web01 |
| 虛擬機(jī)3: web02 | CentOS 6.5 | 10.0.0.10/24 | Web節(jié)點(diǎn)服務(wù)器web02 |
而當(dāng)使用NAT的方式進(jìn)行上網(wǎng)時(shí)虛擬機(jī)、宿主機(jī)之間的網(wǎng)絡(luò)連接關(guān)系可如下所示:
關(guān)于為什么網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)是這樣的,這里不展開說明,可以參考博主的另一篇博文《在實(shí)踐中深入理解VMware虛擬機(jī)的上網(wǎng)模式NAT模式》,這篇文章深入地分析了VMware虛擬機(jī)使用NAT模式上網(wǎng)時(shí)的網(wǎng)絡(luò)結(jié)構(gòu)細(xì)節(jié),相信看完這篇文章后,這里搭建Nginx的實(shí)驗(yàn)環(huán)境也就很容易理解了。
所以首先,應(yīng)該是自己先配置好網(wǎng)絡(luò)環(huán)境,讓宿主機(jī)跟我們的虛擬機(jī)可以通信,實(shí)際上,如果理解了VMware虛擬機(jī)上網(wǎng)方式的原理,同時(shí)對(duì)CentOS的網(wǎng)絡(luò)配置也很熟悉,這一步是可以很輕松完成的,這里就不給出過程了,這里所用的IP地址跟上面的圖示是一樣的。
這里,對(duì)于Nginx的負(fù)載均衡,希望達(dá)到的效果邏輯如下:
當(dāng)用戶訪問我們的Web Server時(shí),實(shí)際上請(qǐng)求是先到達(dá)Nginx負(fù)載均衡器,這就是一個(gè)反向代理的過程了,然后Nginx負(fù)載均衡器再將請(qǐng)求按照一定的調(diào)度算法分發(fā)給相應(yīng)的節(jié)點(diǎn)服務(wù)器。
在整個(gè)實(shí)驗(yàn)環(huán)境中,我們假定web01和web02提供bbs.xpleaf.org的網(wǎng)站內(nèi)容服務(wù),Nginx在web01和web02前面作為反向代理服務(wù)器與負(fù)載均衡服務(wù)器,當(dāng)用戶訪問bbs.xpleaf.org時(shí),Nginx負(fù)載均衡器會(huì)把請(qǐng)求分發(fā)到web01和web02節(jié)點(diǎn)服務(wù)器上,由節(jié)點(diǎn)服務(wù)器返回實(shí)際的內(nèi)容數(shù)據(jù)。
2.配置與測(cè)試實(shí)戰(zhàn):節(jié)點(diǎn)服務(wù)器單虛擬機(jī)場(chǎng)景
這里使用的Nginx的版本為:1.6.3,關(guān)于Nginx的安裝與基本配置,這里不再做說明,可以參考博主前面關(guān)于Nginx的博文,同樣也是給出了詳細(xì)的實(shí)驗(yàn)環(huán)境,可以去實(shí)踐一下。
下面在每臺(tái)web服務(wù)器上,我們只配置了一個(gè)虛擬機(jī),即bbs.xpleaf.org。
(1)web01配置與測(cè)試
- web01作為節(jié)點(diǎn)服務(wù)器,配置它的虛擬機(jī)域名為bbs.xpleaf.org
[root@web01 conf]``# cat nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application``/octet-stream``;
sendfile on;
keepalive_timeout 65;
log_format main ``'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'``;
server {
listen 80;
server_name bbs.xpleaf.org;
location / {
root html``/bbs``;
index index.html index.htm;
}
access_log logs``/access_bbs``.log main;
}
}
|
- 添加相應(yīng)的站點(diǎn)目錄和內(nèi)容
[root@web01 conf]``# cd ../html/bbs/
[root@web01 bbs]``# echo "bbs.xpleaf.org node1 10.0.0.9">index.html
[root@web01 bbs]``# cat index.html
bbs.xpleaf.org node1 10.0.0.9
|
- 配置hosts解析
[root@web01 bbs]``# echo "127.0.0.1 bbs.xpleaf.org">>/etc/hosts
[root@web01 bbs]``# tail -1 /etc/hosts
127.0.0.1 bbs.xpleaf.org
|
- 檢查配置文件與啟動(dòng)
[root@web01 bbs]``# /application/nginx/sbin/nginx -t
nginx: the configuration ``file /application/nginx-1``.6.3``//conf/nginx``.conf syntax is ok
nginx: configuration ``file /application/nginx-1``.6.3``//conf/nginx``.conf ``test is successful
[root@web01 bbs]``# /application/nginx/sbin/nginx -s reload
|
- 本機(jī)上進(jìn)行測(cè)試
[root@web01 bbs]``# curl bbs.xpleaf.org
bbs.xpleaf.org node1 10.0.0.9
|
(2)web02配置與測(cè)試
- web02作為節(jié)點(diǎn)服務(wù)器,配置它的虛擬機(jī)域名為bbs.xpleaf.org
[root@web02 conf]``# cat nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application``/octet-stream``;
sendfile on;
keepalive_timeout 65;
log_format main ``'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'``;
server {
listen 80;
server_name bbs.xpleaf.org;
location / {
root html``/bbs``;
index index.html index.htm;
}
access_log logs``/access_bbs``.log main;
}
}
|
- 添加相應(yīng)的站點(diǎn)目錄和內(nèi)容
[root@web01 conf]``# cd ../html/bbs/
[root@web01 bbs]``# echo "bbs.xpleaf.org node2 10.0.0.10">index.html
[root@web01 bbs]``# cat index.html
bbs.xpleaf.org node2 10.0.0.10
|
- 配置hosts解析
[root@web01 bbs]``# echo "127.0.0.1 bbs.xpleaf.org">>/etc/hosts
[root@web01 bbs]``# tail -1 /etc/hosts
127.0.0.1 bbs.xpleaf.org
|
- 檢查配置文件與啟動(dòng)
[root@web01 bbs]``# /application/nginx/sbin/nginx -t
nginx: the configuration ``file /application/nginx-1``.6.3``//conf/nginx``.conf syntax is ok
nginx: configuration ``file /application/nginx-1``.6.3``//conf/nginx``.conf ``test is successful
[root@web01 bbs]``# /application/nginx/sbin/nginx -s reload
|
- 本機(jī)上進(jìn)行測(cè)試
[root@web02 bbs]``# curl bbs.xpleaf.org
bbs.xpleaf.org node2 10.0.0.10
|
(3)lb01配置
- 配置文件內(nèi)容
[root@lb01 conf]``# cat nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application``/octet-stream``;
sendfile on;
keepalive_timeout 65;
upstream bbs_server_pools {
server 10.0.0.9:80 weight=1;
server 10.0.0.10:80 weight=1;
}
server {
listen 80;
server_name bbs.xpleaf.org;
location / {
proxy_pass http:``//bbs_server_pools``;
}
}
}
|
- 配置hosts解析
[root@web01 bbs]``# echo "127.0.0.1 bbs.xpleaf.org">>/etc/hosts
[root@web01 bbs]``# tail -1 /etc/hosts
127.0.0.1 bbs.xpleaf.org
|
- 檢查配置文件與啟動(dòng)
[root@web01 bbs]``# /application/nginx/sbin/nginx -t
nginx: the configuration ``file /application/nginx-1``.6.3``//conf/nginx``.conf syntax is ok
nginx: configuration ``file /application/nginx-1``.6.3``//conf/nginx``.conf ``test is successful
[root@web01 bbs]``# /application/nginx/sbin/nginx -s reload
|
(4)Nginx負(fù)載均衡效果測(cè)試
可以通過命令行的方式在lb01上進(jìn)行測(cè)試,如下:
[root@lb01 conf]``# curl bbs.xpleaf.org
bbs.xpleaf.org node1 10.0.0.9
[root@lb01 conf]``# curl bbs.xpleaf.org
bbs.xpleaf.org node2 10.0.0.10
[root@lb01 conf]``# curl bbs.xpleaf.org
bbs.xpleaf.org node1 10.0.0.9
[root@lb01 conf]``# curl bbs.xpleaf.org
bbs.xpleaf.org node2 10.0.0.10
[root@lb01 conf]``# curl bbs.xpleaf.org
bbs.xpleaf.org node1 10.0.0.9
[root@lb01 conf]``# curl bbs.xpleaf.org
bbs.xpleaf.org node2 10.0.0.10
|
通過上面的測(cè)試可以知道,訪問請(qǐng)求都被分擔(dān)到兩臺(tái)節(jié)點(diǎn)服務(wù)器上,也可以通過在windows 7的瀏覽器上輸入地址來進(jìn)行測(cè)試(需要先把"127.0.0.1 bbs.xpleaf.org"添加到windows 7的hosts文件中):
3.進(jìn)階1:記錄訪問用戶的實(shí)際IP地址
(1)原理
上面我們通過windows 7進(jìn)行訪問時(shí),查看web服務(wù)器的日志:
[root@web01 bbs]``# tail -2 /application/nginx/logs/access_bbs.log
10.0.0.7 - - [04``/Mar/2017``:11:33:00 +0800] ``"GET / HTTP/1.0" 200 30 ``"-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" "-"
10.0.0.7 - - [04``/Mar/2017``:11:33:29 +0800] ``"GET / HTTP/1.0" 304 0 ``"-" "Mozilla``/5``.0 (Windows NT 6.1;
|
因?yàn)樵谂渲脀eb服務(wù)器節(jié)點(diǎn)時(shí),配置的日志格式是這樣的:
log_format main ``'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'``;
|
所以前面日志的第一個(gè)字段用來記錄Nginx均衡服務(wù)器的地址,這沒有問題,但是最后一個(gè)字段是'-',也就是沒有記錄,該字段是用來記錄用戶的實(shí)際IP的。
(2)配置Nginx攜帶用戶實(shí)際IP
為了能夠讓web服務(wù)器記錄用戶的實(shí)際IP,需要在Nginx負(fù)載均衡服務(wù)器上做如下配置:
[root@lb01 conf]``# cat nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application``/octet-stream``;
sendfile on;
keepalive_timeout 65;
upstream bbs_server_pools { ``# 定義節(jié)點(diǎn)資源池
server 10.0.0.9:80 weight=1;
server 10.0.0.10:80 weight=1;
}
server {
listen 80;
server_name bbs.xpleaf.org;
location / {
proxy_pass http:``//bbs_server_pools``; ``# 把請(qǐng)求轉(zhuǎn)發(fā)到節(jié)點(diǎn)資源池中指定的主機(jī)中
proxy_set_header X-Forwarded-For $remote_addr;
}
}
}
實(shí)際上就是多加了最后一行。
(3)測(cè)試
這時(shí)再用windows 7去訪問bbs.xpleaf.org,然后在web服務(wù)器上查看日志信息:
[root@web01 bbs]``# tail -2 /application/nginx/logs/access_bbs.log
10.0.0.7 - - [04``/Mar/2017``:11:49:10 +0800] ``"GET / HTTP/1.0" 200 30 ``"-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" "10.0.0.1"
10.0.0.7 - - [04``/Mar/2017``:11:49:11 +0800] ``"GET / HTTP/1.0" 200 30 ``"-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" "10.0.0.1"
可以看到日志的最后一個(gè)字段就記錄了客戶端的真實(shí)IP地址。
4.進(jìn)階2:節(jié)點(diǎn)服務(wù)器多虛擬機(jī)場(chǎng)景
前面在每臺(tái)web服務(wù)器上,只配置了一個(gè)站點(diǎn)bbs.xpleaf.org,所以上面的負(fù)載均衡是沒有問題,但是如果再配置一個(gè)站點(diǎn)blog.xpleaf.org(即在bbs.xpleaf.org后面再增加一個(gè)server域),當(dāng)去測(cè)試時(shí)就會(huì)發(fā)現(xiàn),無論是訪問bbs.xpleaf.org,還是訪問blog.xpleaf.org,返回的內(nèi)容都是站點(diǎn)bbs.xpleaf.org的內(nèi)容。
究其原因是當(dāng)用戶訪問域名時(shí)確實(shí)是攜帶了blog.xpleaf.org主機(jī)頭請(qǐng)求Nginx反向代理服務(wù)器,但是是反向代理服務(wù)器向下面節(jié)點(diǎn)重新發(fā)起請(qǐng)求時(shí),默認(rèn)并沒有在請(qǐng)求頭里告訴節(jié)點(diǎn)服務(wù)器要找哪臺(tái)虛擬主機(jī),所以web節(jié)點(diǎn)服務(wù)器接收到請(qǐng)求后發(fā)現(xiàn)沒有主機(jī)頭信息,因此,就把節(jié)點(diǎn)服務(wù)器的第一個(gè) 虛擬機(jī)發(fā)給了反向代理。
解決方法是,當(dāng)反向代理向后重新發(fā)起請(qǐng)求時(shí),要攜帶主機(jī)頭信息,以明確告訴節(jié)點(diǎn)服務(wù)器要找哪個(gè)虛擬機(jī)。只需要在Nginx負(fù)載均衡服務(wù)器上增加下面一行配置:
proxy_set_header Host $host;
|
此時(shí)配置文件內(nèi)容如下:
`[root@lb01 conf]``# cat nginx.conf`
`worker_processes 1;`
`events {`
`worker_connections 1024;`
`}`
`http {`
`include mime.types;`
`default_type application``/octet-stream``;`
`sendfile on;`
`keepalive_timeout 65;`
`upstream bbs_server_pools {`
`server 10.0.0.9:80 weight=1;`
`server 10.0.0.10:80 weight=1;`
`}`
`server {`
`listen 80;`
`server_name bbs.xpleaf.org;`
`location / {`
`proxy_pass http:``//bbs_server_pools``;`
`proxy_set_header X-Forwarded-For $remote_addr;`
`proxy_set_header Host $host;`
`}`
`}`
`}`
|
由于原理比較簡(jiǎn)單,這里就不給出完整過程了,可以參考老男孩老師的書籍。
5.進(jìn)階3:根據(jù)URL中的目錄地址實(shí)現(xiàn)代理轉(zhuǎn)發(fā)
根據(jù)HTTP的URL進(jìn)行轉(zhuǎn)發(fā)的應(yīng)用情況,被稱為第7層(應(yīng)用層)的負(fù)載均衡,而LVS的負(fù)載均衡一般用于TCP等的轉(zhuǎn)發(fā),因此被稱為第4層轉(zhuǎn)發(fā)(傳輸層)的負(fù)載均衡。
在上面的案例中,如果需要實(shí)現(xiàn)一個(gè)需求,希望bbs.xpleaf.org可以使用bbs.xpleaf.org/upload來提供上傳服務(wù),而bbs.xpleaf.org則保持默認(rèn)提供網(wǎng)站的主頁內(nèi)容,這時(shí)就可以使用Nginx基于URL來實(shí)現(xiàn)代理轉(zhuǎn)發(fā)了。
可以把lb01的Nginx配置修改為如下:
`[root@lb01 conf]``# cat nginx.conf`
`worker_processes 1;`
`events {`
`worker_connections 1024;`
`}`
`http {`
`include mime.types;`
`default_type application``/octet-stream``;`
`sendfile on;`
`keepalive_timeout 65;`
`upstream bbs_server_pools {`
`server 10.0.0.9:80 weight=1;`
`}`
`upstream bbs_upload_server_pools {`
`server 10.0.0.10:80 weight=1;`
`}`
`server {`
`listen 80;`
`server_name bbs.xpleaf.org;`
`location / {`
`proxy_pass http:``//bbs_server_pools``;`
`}`
`location ``/static` `{`
`proxy_pass http:``//bbs_upload_server_pools``;`
`}`
`}`
`}`
|
這樣,實(shí)際上就相當(dāng)于bbs.xpleaf.org提供了兩種不同的業(yè)務(wù),一種是普通的bbs論壇內(nèi)容業(yè)務(wù),另外一種則是上傳業(yè)務(wù),上面我們定義了兩個(gè)地址池,在每個(gè)地址池中,如果有多臺(tái)節(jié)點(diǎn)服務(wù)器,就可以根據(jù)upstream的相關(guān)調(diào)度算法來實(shí)現(xiàn)不同業(yè)務(wù)的負(fù)載均衡了,總結(jié)來說就是,只使用一個(gè)域名對(duì)外提供服務(wù),同時(shí)該域名對(duì)外提供不同的產(chǎn)品業(yè)務(wù)。
當(dāng)然,基于這種思想,通過location的正則匹配,可以根據(jù)用戶不同的瀏覽器版本來訪問不同的服務(wù)器群、根據(jù)設(shè)備的不同類型來訪問不同的服務(wù)器群(PC端和移動(dòng)端)、根據(jù)文件擴(kuò)展名來訪問不同的服務(wù)器群(實(shí)現(xiàn)動(dòng)靜分離),從而可以提升用戶的體驗(yàn)。相關(guān)案例可以參考老男孩老師的書籍。
6.原理解析:http proxy模塊和upstream模塊
Nginx的反向代理功能和負(fù)載均衡功能是通過http proxy模塊和upstream模塊來實(shí)現(xiàn)的:
| Nginx http功能模塊 | 模塊說明 |
| ngx_http_proxy_module | proxy代理模塊,用于把請(qǐng)求后拋給服務(wù)器節(jié)點(diǎn)或upstream服務(wù)器池 |
| ngx_http_upstream_module | 負(fù)載均衡模塊,可以實(shí)現(xiàn)網(wǎng)站的負(fù)載均衡功能及節(jié)點(diǎn)的健康檢查 |
(1)http proxy模塊
配置方法可以參考上面的案例,實(shí)際上還有很多參數(shù)可以使用,這里不詳細(xì)給出。
(2)upstream模塊
主要介紹一下upstream模塊在實(shí)現(xiàn)負(fù)載均衡功能時(shí)的調(diào)度算法,其實(shí)關(guān)于upstream的調(diào)度算法,如果學(xué)習(xí)過QoS,看起來就會(huì)覺得很熟悉了。
- 靜態(tài)調(diào)度算法:負(fù)載均衡器根據(jù)自身設(shè)定的規(guī)則進(jìn)行分配,不需要考慮后端節(jié)點(diǎn)服務(wù)器的情況
主要有rr、wrr、ip_hash
(1)rr輪詢
如果節(jié)點(diǎn)服務(wù)器不宕機(jī),請(qǐng)求將會(huì)平均分發(fā)到各節(jié)點(diǎn)服務(wù)器上;
(2)wrr權(quán)重輪詢
按照設(shè)置的weight權(quán)重,將請(qǐng)示按比例分發(fā)到各節(jié)點(diǎn)服務(wù)器上;
(3)ip_hash
按照客戶端IP的``hash``結(jié)果分配;
可以解決動(dòng)態(tài)網(wǎng)頁的session共享問題(會(huì)話保持),但無法保證1:1的負(fù)載均衡;
|
- 動(dòng)態(tài)調(diào)度算法:負(fù)載均衡器會(huì)根據(jù)后端節(jié)點(diǎn)的當(dāng)前狀態(tài)來決定是否分發(fā)請(qǐng)求
主要有fair、least_conn、url_hash、一致性``hash``算法
(1)fair
根據(jù)后端節(jié)點(diǎn)服務(wù)器的響應(yīng)時(shí)間來分配請(qǐng)求,響應(yīng)時(shí)間短的優(yōu)先分配;
Nginx本身不支持該算法,需要下載相關(guān)模塊upstream_fair;
(2)least_conn
根據(jù)后端節(jié)點(diǎn)的連接數(shù)來決定分配情況,哪個(gè)機(jī)器連接數(shù)少就分發(fā);
(3)url_hash(第三方調(diào)度算法)
與ip_hash類似,根據(jù)訪問URL來分配請(qǐng)求,讓每個(gè)URL定向到同一個(gè)后端服務(wù)器;
后端服務(wù)器為緩存服務(wù)器時(shí)效果顯著;
(4)一致性``hash``算法(第三方調(diào)度算法)
比較復(fù)雜,這里不做介紹。
|
7.下一步做什么
首先當(dāng)然是要能夠把Nginx負(fù)載均衡的環(huán)境搭建出來,否則是沒有辦法繼續(xù)往下面學(xué)習(xí)的,然后就是繼續(xù)加深Nginx負(fù)載均衡的理解,同時(shí)也在實(shí)際場(chǎng)景中多分析和嘗試使用。
實(shí)際場(chǎng)景:給flume,elasticsearch,web應(yīng)用做負(fù)載均衡




