.說明
常見的集群架構及相關軟件,可以參考下面的導圖:
互聯網企業常用的是負載均衡集群和高可用性集群,負載均衡集群強調“分擔”,通過一定的調度算法 ,可以實現用多個節點服務器來分擔用戶的訪問請求和數據流量;高可用性集群強調“高可用”,即一個節點失效了,它的任務可以立刻轉移到另一個備份的節點上(即一般通過設置主備來實現)。顯然因為負載均衡集群使用多個節點來分擔服務,即使其中一個節點失效了,其它節點也可以繼續工作,因此它也具有高可用性。
下面介紹的是Nginx負載均衡的配置,同時也給出了實驗環境。
1.實驗環境說明
本次實驗的測試環境使用的宿主機操作系統為Windows 7,在Vmware虛擬機安裝CentOS 6.5(3臺),說明如下:
主機類型 | 操作系統 | IP地址 | 作用 |
---|---|---|---|
宿主機 | Windows 7 | 10.0.0.1/24(VMnet8的IP地址) | 遠程3臺虛擬機,進行配置,同時也作為后面測試使用的客戶端 |
虛擬機1: lb01 | CentOS 6.5 | 10.0.0.7/24 | 負載均衡服務器lb01,將請求分擔到Web節點服務器中 |
虛擬機2: web01 | CentOS 6.5 | 10.0.0.9/24 | Web節點服務器web01 |
虛擬機3: web02 | CentOS 6.5 | 10.0.0.10/24 | Web節點服務器web02 |
而當使用NAT的方式進行上網時虛擬機、宿主機之間的網絡連接關系可如下所示:
關于為什么網絡拓撲結構是這樣的,這里不展開說明,可以參考博主的另一篇博文《在實踐中深入理解VMware虛擬機的上網模式NAT模式》,這篇文章深入地分析了VMware虛擬機使用NAT模式上網時的網絡結構細節,相信看完這篇文章后,這里搭建Nginx的實驗環境也就很容易理解了。
所以首先,應該是自己先配置好網絡環境,讓宿主機跟我們的虛擬機可以通信,實際上,如果理解了VMware虛擬機上網方式的原理,同時對CentOS的網絡配置也很熟悉,這一步是可以很輕松完成的,這里就不給出過程了,這里所用的IP地址跟上面的圖示是一樣的。
這里,對于Nginx的負載均衡,希望達到的效果邏輯如下:
當用戶訪問我們的Web Server時,實際上請求是先到達Nginx負載均衡器,這就是一個反向代理的過程了,然后Nginx負載均衡器再將請求按照一定的調度算法分發給相應的節點服務器。
在整個實驗環境中,我們假定web01和web02提供bbs.xpleaf.org的網站內容服務,Nginx在web01和web02前面作為反向代理服務器與負載均衡服務器,當用戶訪問bbs.xpleaf.org時,Nginx負載均衡器會把請求分發到web01和web02節點服務器上,由節點服務器返回實際的內容數據。
2.配置與測試實戰:節點服務器單虛擬機場景
這里使用的Nginx的版本為:1.6.3,關于Nginx的安裝與基本配置,這里不再做說明,可以參考博主前面關于Nginx的博文,同樣也是給出了詳細的實驗環境,可以去實踐一下。
下面在每臺web服務器上,我們只配置了一個虛擬機,即bbs.xpleaf.org。
(1)web01配置與測試
- web01作為節點服務器,配置它的虛擬機域名為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;
}
}
|
- 添加相應的站點目錄和內容
[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
|
- 檢查配置文件與啟動
[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
|
- 本機上進行測試
[root@web01 bbs]``# curl bbs.xpleaf.org
bbs.xpleaf.org node1 10.0.0.9
|
(2)web02配置與測試
- web02作為節點服務器,配置它的虛擬機域名為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;
}
}
|
- 添加相應的站點目錄和內容
[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
|
- 檢查配置文件與啟動
[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
|
- 本機上進行測試
[root@web02 bbs]``# curl bbs.xpleaf.org
bbs.xpleaf.org node2 10.0.0.10
|
(3)lb01配置
- 配置文件內容
[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
|
- 檢查配置文件與啟動
[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負載均衡效果測試
可以通過命令行的方式在lb01上進行測試,如下:
[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
|
通過上面的測試可以知道,訪問請求都被分擔到兩臺節點服務器上,也可以通過在windows 7的瀏覽器上輸入地址來進行測試(需要先把"127.0.0.1 bbs.xpleaf.org"添加到windows 7的hosts文件中):
3.進階1:記錄訪問用戶的實際IP地址
(1)原理
上面我們通過windows 7進行訪問時,查看web服務器的日志:
[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;
|
因為在配置web服務器節點時,配置的日志格式是這樣的:
log_format main ``'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'``;
|
所以前面日志的第一個字段用來記錄Nginx均衡服務器的地址,這沒有問題,但是最后一個字段是'-',也就是沒有記錄,該字段是用來記錄用戶的實際IP的。
(2)配置Nginx攜帶用戶實際IP
為了能夠讓web服務器記錄用戶的實際IP,需要在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;
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;
}
}
}
實際上就是多加了最后一行。
(3)測試
這時再用windows 7去訪問bbs.xpleaf.org,然后在web服務器上查看日志信息:
[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"
可以看到日志的最后一個字段就記錄了客戶端的真實IP地址。
4.進階2:節點服務器多虛擬機場景
前面在每臺web服務器上,只配置了一個站點bbs.xpleaf.org,所以上面的負載均衡是沒有問題,但是如果再配置一個站點blog.xpleaf.org(即在bbs.xpleaf.org后面再增加一個server域),當去測試時就會發現,無論是訪問bbs.xpleaf.org,還是訪問blog.xpleaf.org,返回的內容都是站點bbs.xpleaf.org的內容。
究其原因是當用戶訪問域名時確實是攜帶了blog.xpleaf.org主機頭請求Nginx反向代理服務器,但是是反向代理服務器向下面節點重新發起請求時,默認并沒有在請求頭里告訴節點服務器要找哪臺虛擬主機,所以web節點服務器接收到請求后發現沒有主機頭信息,因此,就把節點服務器的第一個 虛擬機發給了反向代理。
解決方法是,當反向代理向后重新發起請求時,要攜帶主機頭信息,以明確告訴節點服務器要找哪個虛擬機。只需要在Nginx負載均衡服務器上增加下面一行配置:
proxy_set_header Host $host;
|
此時配置文件內容如下:
`[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;`
`}`
`}`
`}`
|
由于原理比較簡單,這里就不給出完整過程了,可以參考老男孩老師的書籍。
5.進階3:根據URL中的目錄地址實現代理轉發
根據HTTP的URL進行轉發的應用情況,被稱為第7層(應用層)的負載均衡,而LVS的負載均衡一般用于TCP等的轉發,因此被稱為第4層轉發(傳輸層)的負載均衡。
在上面的案例中,如果需要實現一個需求,希望bbs.xpleaf.org可以使用bbs.xpleaf.org/upload來提供上傳服務,而bbs.xpleaf.org則保持默認提供網站的主頁內容,這時就可以使用Nginx基于URL來實現代理轉發了。
可以把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``;`
`}`
`}`
`}`
|
這樣,實際上就相當于bbs.xpleaf.org提供了兩種不同的業務,一種是普通的bbs論壇內容業務,另外一種則是上傳業務,上面我們定義了兩個地址池,在每個地址池中,如果有多臺節點服務器,就可以根據upstream的相關調度算法來實現不同業務的負載均衡了,總結來說就是,只使用一個域名對外提供服務,同時該域名對外提供不同的產品業務。
當然,基于這種思想,通過location的正則匹配,可以根據用戶不同的瀏覽器版本來訪問不同的服務器群、根據設備的不同類型來訪問不同的服務器群(PC端和移動端)、根據文件擴展名來訪問不同的服務器群(實現動靜分離),從而可以提升用戶的體驗。相關案例可以參考老男孩老師的書籍。
6.原理解析:http proxy模塊和upstream模塊
Nginx的反向代理功能和負載均衡功能是通過http proxy模塊和upstream模塊來實現的:
| Nginx http功能模塊 | 模塊說明 |
| ngx_http_proxy_module | proxy代理模塊,用于把請求后拋給服務器節點或upstream服務器池 |
| ngx_http_upstream_module | 負載均衡模塊,可以實現網站的負載均衡功能及節點的健康檢查 |
(1)http proxy模塊
配置方法可以參考上面的案例,實際上還有很多參數可以使用,這里不詳細給出。
(2)upstream模塊
主要介紹一下upstream模塊在實現負載均衡功能時的調度算法,其實關于upstream的調度算法,如果學習過QoS,看起來就會覺得很熟悉了。
- 靜態調度算法:負載均衡器根據自身設定的規則進行分配,不需要考慮后端節點服務器的情況
主要有rr、wrr、ip_hash
(1)rr輪詢
如果節點服務器不宕機,請求將會平均分發到各節點服務器上;
(2)wrr權重輪詢
按照設置的weight權重,將請示按比例分發到各節點服務器上;
(3)ip_hash
按照客戶端IP的``hash``結果分配;
可以解決動態網頁的session共享問題(會話保持),但無法保證1:1的負載均衡;
|
- 動態調度算法:負載均衡器會根據后端節點的當前狀態來決定是否分發請求
主要有fair、least_conn、url_hash、一致性``hash``算法
(1)fair
根據后端節點服務器的響應時間來分配請求,響應時間短的優先分配;
Nginx本身不支持該算法,需要下載相關模塊upstream_fair;
(2)least_conn
根據后端節點的連接數來決定分配情況,哪個機器連接數少就分發;
(3)url_hash(第三方調度算法)
與ip_hash類似,根據訪問URL來分配請求,讓每個URL定向到同一個后端服務器;
后端服務器為緩存服務器時效果顯著;
(4)一致性``hash``算法(第三方調度算法)
比較復雜,這里不做介紹。
|
7.下一步做什么
首先當然是要能夠把Nginx負載均衡的環境搭建出來,否則是沒有辦法繼續往下面學習的,然后就是繼續加深Nginx負載均衡的理解,同時也在實際場景中多分析和嘗試使用。
實際場景:給flume,elasticsearch,web應用做負載均衡