Nginx反向代理與負載均衡:節點服務器單/多虛擬機配置+實驗環境搭建+原理解析

.說明
常見的集群架構及相關軟件,可以參考下面的導圖:


互聯網企業常用的是負載均衡集群和高可用性集群,負載均衡集群強調“分擔”,通過一定的調度算法 ,可以實現用多個節點服務器來分擔用戶的訪問請求和數據流量;高可用性集群強調“高可用”,即一個節點失效了,它的任務可以立刻轉移到另一個備份的節點上(即一般通過設置主備來實現)。顯然因為負載均衡集群使用多個節點來分擔服務,即使其中一個節點失效了,其它節點也可以繼續工作,因此它也具有高可用性。
下面介紹的是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應用做負載均衡

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容