(1)lb配置
配置文件內容
[root@lb conf]# cat nginx.conf
worker_processes ;
events {
worker_connections ;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout ;
upstream bbs_server_pools {
server ...: weight=;
server ...: weight=;
}
server {
listen ;
server_name bbs.xpleaf.org;
location / {
proxy_pass http://bbs_server_pools;
}
}
}
配置hosts解析
[root@web bbs]# echo "... bbs.xpleaf.org">>/etc/hosts
[root@web bbs]# tail - /etc/hosts
... bbs.xpleaf.org
檢查配置文件與啓動
[root@web bbs]# /application/nginx/sbin/nginx -t
nginx: the configuration file /application/nginx-..//conf/nginx.conf syntax is ok
nginx: configuration file /application/nginx-..//conf/nginx.conf test is successful
[root@web bbs]# /application/nginx/sbin/nginx -s reload
(2)Nginx負載均衡效果測試
可以通過命令行的方式在lb上進行測試,如下:
[root@lb conf]# curl bbs.xpleaf.org
bbs.xpleaf.org node ...
[root@lb conf]# curl bbs.xpleaf.org
bbs.xpleaf.org node ...
[root@lb conf]# curl bbs.xpleaf.org
bbs.xpleaf.org node ...
[root@lb conf]# curl bbs.xpleaf.org
bbs.xpleaf.org node ...
[root@lb conf]# curl bbs.xpleaf.org
bbs.xpleaf.org node ...
[root@lb conf]# curl bbs.xpleaf.org
bbs.xpleaf.org node ...
通過上面的測試可以知道,訪問請求都被分擔到兩臺節點服務器上,也可以通過在windows 的瀏覽器上輸入地址來進行測試(需要先把"... bbs.xpleaf.org"添加到windows 的hosts文件中):
wKiomiwwXAcmqBAABBwpak.png
wKiomiwwWSoVoRAABphWSidw.png
.進階:記錄訪問用戶的實際IP地址
(3)原理
上面我們通過windows 進行訪問時,查看web服務器的日誌:
[root@web bbs]# tail - /application/nginx/logs/access_bbs.log
... - - [/Mar/::: +] "GET / HTTP/." "-" "Mozilla/. (Windows NT .; WOW) AppleWebKit/. (KHTML, like Gecko) Chrome/... Safari/." "-"
... - - [/Mar/::: +] "GET / HTTP/." "-" "Mozilla/. (Windows NT .;
因爲在配置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的。
(4)配置Nginx攜帶用戶實際IP
爲了能夠讓web服務器記錄用戶的實際IP,需要在Nginx負載均衡服務器上做如下配置:
[root@lb conf]# cat nginx.conf
worker_processes ;
events {
worker_connections ;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout ;
upstream bbs_server_pools { # 定義節點資源池
server ...: weight=;
server ...: weight=;
}
server {
listen ;
server_name bbs.xpleaf.org;
location / {
proxy_pass http://bbs_server_pools; # 把請求轉發到節點資源池中指定的主機中
proxy_set_header X-Forwarded-For $remote_addr;
}
}
}
實際上就是多加了最後一行。
(5)測試
這時再用windows 去訪問bbs.xpleaf.org,然後在web服務器上查看日誌信息:
[root@web bbs]# tail - /application/nginx/logs/access_bbs.log
... - - [/Mar/::: +] "GET / HTTP/." "-" "Mozilla/. (Windows NT .; WOW) AppleWebKit/. (KHTML, like Gecko) Chrome/... Safari/." "..."
... - - [/Mar/::: +] "GET / HTTP/." "-" "Mozilla/. (Windows NT .; WOW) AppleWebKit/. (KHTML, like Gecko) Chrome/... Safari/." "..."
可以看到日誌的最後一個字段就記錄了客戶端的真實IP地址。
.進階:節點服務器多虛擬機場景
前面在每臺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@lb conf]# cat nginx.conf
worker_processes ;
events {
worker_connections ;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout ;
upstream bbs_server_pools {
server ...: weight=;
server ...: weight=;
}
server {
listen ;
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;
}
}
}
由於原理比較簡單,這裏就不給出完整過程了,可以參考老男孩老師的書籍。
.進階:根據URL中的目錄地址實現代理轉發
根據HTTP的URL進行轉發的應用情況,被稱爲第層(應用層)的負載均衡,而LVS的負載均衡一般用於TCP等的轉發,因此被稱爲第層轉發(傳輸層)的負載均衡。
在上面的案例中,如果需要實現一個需求,希望bbs.xpleaf.org可以使用bbs.xpleaf.org/upload來提供上傳服務,而bbs.xpleaf.org則保持默認提供網站的主頁內容,這時就可以使用Nginx基於URL來實現代理轉發了。
可以把lb的Nginx配置修改爲如下:
[root@lb conf]# cat nginx.conf
worker_processes ;
events {
worker_connections ;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout ;
upstream bbs_server_pools {
server ...: weight=;
}
upstream bbs_upload_server_pools {
server ...: weight=;
}
server {
listen ;
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端和移動端)、根據文件擴展名來訪問不同的服務器羣(實現動靜分離),從而可以提升用戶的體驗。相關案例可以參考老男孩老師的書籍。
.原理解析: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
()rr輪詢
如果節點服務器不宕機,請求將會平均分發到各節點服務器上;
()wrr權重輪詢
按照設置的weight權重,將請示按比例分發到各節點服務器上;
()ip_hash
按照客戶端IP的hash結果分配;
可以解決動態網頁的session共享問題(會話保持),但無法保證:的負載均衡;
動態調度算法:負載均衡器會根據後端節點的當前狀態來決定是否分發請求
主要有fair、least_conn、url_hash、一致性hash算法
()fair
根據後端節點服務器的響應時間來分配請求,響應時間短的優先分配;
Nginx本身不支持該算法,需要下載相關模塊upstream_fair;
()least_conn
根據後端節點的連接數來決定分配情況,哪個機器連接數少就分發;
()url_hash(第三方調度算法)
與ip_hash類似,根據訪問URL來分配請求,讓每個URL定向到同一個後端服務器;
後端服務器爲緩存服務器時效果顯著;
()一致性hash算法(第三方調度算法)
比較複雜,這裏不做介紹。
.下一步做什麼
首先當然是要能夠把Nginx負載均衡的環境搭建出來,否則是沒有辦法繼續往下面學習的,然後就是繼續加深Nginx負載均衡的理解,同時也在實際場景中多分析和嘗試使用。