1. 程式人生 > >Nginx反向代理與負載均衡應用實踐

Nginx反向代理與負載均衡應用實踐

Nginx反向代理與負載均衡應用實踐

課堂筆記


 

一、原理

 

1.1 為什麼要使用叢集

(1)高效能

一些國家重要的計算密集型應用(如天氣預報,核試驗模擬等),需要計算機有很強的運算處理能力。以全世界現有的技術,即使是大型機,其計算能力也是有限的,很難單獨完成此任務。因為計算時間可能會相當長,也許幾天,甚至幾年或更久。因此,對於這類複雜的計算業務,便使用了計算機叢集技術,集中幾十上百臺,甚至成千上萬臺計算機進行計算。

假如你配一個LNMP環境,每次只需要服務10個併發請求,那麼單臺伺服器一定會比多個伺服器叢集要快。只有當併發或總請求數量超過單臺伺服器的承受能力時,伺服器叢集才會體現出優勢。

(2)價格有效性

通常一套系統叢集架構,只需要幾臺或數十臺伺服器主機即可。與動輒價值上百萬元的專用超級計算機相比便宜了很多。在達到同樣效能需求的條件下,採用計算機叢集架構比採用同等運算能力的大型計算機具有更高的價效比。 
早期的淘寶,支付寶的資料庫等核心系統就是使用上百萬元的小型機伺服器。後因使用維護成本太高以及擴充套件裝置費用成幾何級數翻倍,甚至成為擴充套件瓶頸,人員維護也十分困難,最終使用PC伺服器叢集替換之,比如,把資料庫系統從小機結合Oracle資料庫遷移到MySQL開源資料庫結合PC伺服器上來。不但成本下降了,擴充套件和維護也更容易了。 
(3)可伸縮性

當服務負載,壓力增長時,針對集群系統進行較簡單的擴充套件即可滿足需求,且不會降低服務質量。

通常情況下,硬體裝置若想擴充套件效能,不得不增加新的CPU和儲存器裝置,如果加不上去了,就不得不夠買更高效能的伺服器,就拿我們現在的伺服器來講,可以增加的裝置總是有限的。如果採用叢集技術,則只需要將新的單個伺服器加入現有叢集架構中即可,從訪問的客戶角度來看,系統服務無論是連續性還是效能上都幾乎沒有變化,系統在不知不覺中完成了升級,加大了訪問能力,輕鬆地實現了擴充套件。集群系統中的節點數目可以增長到幾千乃至上萬個,其伸縮性遠超過單臺超級計算機。

(4)高可用性

單一的計算機系統總會面臨裝置損毀的問題,如CPU,記憶體,主機板,電源,硬碟等,只要一個部件壞掉,這個計算機系統就可能會宕機,無法正常提供服務。在集群系統中,儘管部分硬體和軟體也還是會發生故障,但整個系統的服務可以是7*24小時可用的。 
叢集架構技術可以使得系統在若干硬體裝置故障發生時仍可以繼續工作,這樣就將系統的停機時間減少到了最小。集群系統在提高系統可靠性的同時,也大大減小了系統故障帶來的業務損失,目前幾乎100%的網際網路網站都要求7*24小時提供服務。 
(5)透明性

多個獨立計算機組成的鬆耦合集群系統構成一個虛擬伺服器。使用者或客戶端程式訪問集群系統時,就像訪問一臺高效能,高可用的伺服器一樣,叢集中一部分伺服器的上線,下線不會中斷整個系統服務,這對使用者也是透明的。

(6)可管理性

整個系統可能在物理上很大,但其實容易管理,就像管理一個單一映像系統一樣。在理想狀況下,軟硬體模組的插入能做到即插即用。

(7)可程式設計性

在集群系統上,容易開發及修改各類應用程式。

 

1.2、叢集的常見分類

計算機叢集架構按功能和結構可以分成以下幾類: 
1、負載均衡叢集,簡稱LBC或者LB 
2、高可用性叢集,簡稱HAC 
3、高效能運算叢集,簡稱HPC 
4、網格計算叢集 
5、負載均衡叢集和高可用性叢集是網際網路行業常用的叢集架構模式

 

1.3、不同種類的叢集介紹

1、負載均衡叢集

負載均衡叢集為企業提供了更為實用,價效比更高的系統架構解決方案。負載均衡叢集可以把很多客戶集中的訪問請求負載壓力盡可能平均地分攤在計算機叢集中處理。客戶訪問請求負載通常包括應用程式處理負載和網路流量負載。這樣的系統非常適合使用同一組應用程式為大量使用者提供服務的模式,每個節點都可以承擔一定的訪問請求負載壓力,並且可以實現訪問請求在各節點之間動態分配,以實現負載均衡。 
負載均衡叢集執行時,一般是通過一個或多個前端負載均衡器將客戶訪問請求分發到後端的一組伺服器上,從而達到整個系統的高效能和高可用性。一般高可用性叢集和負載均衡叢集會使用類似的技術,或同時具有高可用性與負載均衡的特點。

(1)負載均衡叢集的作用為:

分攤使用者訪問請求及資料流量(負載均衡) 
保持業務連續性,即7*24小時服務(高可用性) 
應用於Web業務及資料庫從庫等伺服器的業務

負載均衡叢集典型的開源軟體包括LVS,Nginx,Haproxy等。如下圖所示: 
image_1crs7rku611er1if91oqu1p2t4nh9.png-213.5kB

2、高可用性叢集

一般是指在叢集中任意一個節點失效的情況下,該節點上的所有任務會自動轉移到其他正常的節點上。此過程並不影響整個叢集的執行。 
當叢集中的一個節點系統發生故障時,執行著的叢集服務會迅速作出反應,將該系統的服務分配到叢集中其他正在工作的系統上執行。考慮到計算機硬體和軟體的容錯性,高可用性叢集的主要目的是使叢集的整體服務儘可能可用。如果高可用性叢集中的主節點發生了故障,那麼這段時間內將由備節點代替它。備節點通常是主節點的映象。當它代替主節點時,它可以完全接管主節點(包括IP地址及其他資源)提供服務,因此,使集群系統環境對於使用者來說是一致的,既不會影響使用者的訪問。 
高可用性叢集使伺服器系統的執行速度和響應速度會盡可能的快。他們經常利用在多臺機器上執行的冗餘節點和服務來相互跟蹤。如果某個節點失敗,它的替補者將在幾秒鐘或更短時間內接管它的職責。因此,對於使用者而言,叢集裡的任意一臺機器宕機,業務都不會受影響(理論情況下)。

高可用性叢集的作用為: 
當一臺機器宕機時,另外一臺機器接管宕機的機器的IP資源和服務資源,提供服務。 
常用於不易實現負載均衡的應用,比如負載均衡器,主資料庫,主儲存對之間。 
高可用性叢集常用的開源軟體包括Keepalived,Heartbeat等,其架構圖如下圖所示: 
image_1crs80p9u183vadkjrvd3p1dusm.png-214.9kB

3、高效能運算叢集

高效能運算叢集也稱平行計算。通常,高效能運算叢集涉及為叢集開發的並行應用程式,以解決複雜的科學問題(天氣預報,石油勘探,核反應模擬等)。高效能運算叢集對外就好像一個超級計算機,這種超級計算機內部由數十至上萬個獨立伺服器組成,並且在公共訊息傳遞層上進行通訊以執行並行應用程式。在生產環境中實際就是把任務切成蛋糕,然後下發到叢集節點計算,計算後返回結果,然後繼續領新任務計算,如此往復。

在網際網路網站運維中,比較常用的就是負載均衡叢集和高可用性叢集

 

1.4、LVS介紹

LVS是Linux Virtual Server的簡寫,意即Linux虛擬伺服器,是一個虛擬的伺服器集群系統。 
特點是:可伸縮網路服務的幾種結構,它們都需要一個前端的負載排程器(或者多個進行主從備份)。我們先分析實現虛擬網路服務的主要技術,指出IP負載均衡技術是在負載排程器的實現技術中效率最高的。在已有的IP負載均衡技術中,主要有通過網路地址轉換(Network Address Translation)將一組伺服器構成一個高效能的、高可用的虛擬伺服器,我們稱之為VS/NAT技術(Virtual Server via Network Address Translation)。在分析VS/NAT的缺點和網路服務的非對稱性的基礎上,我們提出了通過IP隧道實現虛擬伺服器的方法VS/TUN (Virtual Server via IP Tunneling),和通過直接路由實現虛擬伺服器的方法VS/DR(Virtual Server via Direct Routing),它們可以極大地提高系統的伸縮性。VS/NAT、VS/TUN和VS/DR技術是LVS叢集中實現的三種IP負載均衡技術。

lvs是四層負載均衡,因為他工作在四層網路模型上,即為傳輸層。他不會執行tcp三次握手,他是通過轉發使用者請求來實現負載均衡,轉發到後方的web伺服器,使用者是跟後面的web伺服器執行的tcp三次握手。他支援極大的併發,效率及其高。資料統計基本可以實現30萬併發。即為4層轉發。

 

1.5、Nginx負載均衡叢集介紹

1、搭建負載均衡服務的需求 
負載均衡叢集提供了一種廉價,有效,透明的方法,來擴充套件網路裝置和伺服器的負載,頻寬和吞吐量,同時加強了網路資料處理能力,提高了網路的靈活性和可用性。

搭建負載均衡服務的需求如下:

(1)把單臺計算機無法承受的大規模併發訪問或資料流量分擔到多臺節點裝置上,分別進行處理,減少使用者等待響應的時間,提升使用者體驗。 
(2)單個重負載的運算分擔到多臺節點裝置上做並行處理,每個節點裝置處理結束後,將結果彙總,返回給使用者,系統處理能力得到大幅度提高。 
(3)7*24小時的服務保證,任意一個或多個有限後面節點裝置宕機,不能影響業務。

在負載均衡叢集中,同組叢集的所有計算機節點都應該提供相同的服務。叢集負載均衡器會截獲所有對該服務的入站請求。然後將這些請求儘可能地平均地分配在所有叢集節點上。

2 、Nginx負載均衡叢集介紹

(1)反向代理與負載均衡概念簡介

嚴格地說,Nginx僅僅是作為Nginx Proxy反向代理使用的,因為這個反向代理功能表現的效果是負載均衡叢集的效果,所以本文稱之為Nginx負載均衡。那麼,反向代理和負載均衡有什麼區別呢? 
普通負載均衡軟體,例如大名鼎鼎的LVS,其實功能只是對請求資料包的轉發(也可能會改寫資料包),傳遞,其中DR模式明顯的特徵是從負載均衡下面的節點伺服器來看,接收到的請求還是來自訪問負載均衡器的客戶端的真實使用者,而反向代理就不一樣了,反向代理接收訪問使用者的請求後,會代理使用者重新發起請求代理下的節點伺服器,最後把資料返回給客戶端使用者,在節點伺服器看來,訪問的節點伺服器的客戶端使用者就是反向代理伺服器了,而非真實的網站訪問使用者。 
一句話,LVS等的負載均衡是轉發使用者請求的資料包,而Nginx反向代理是接收使用者的請求然後重新發起請求去請求其後面的節點。

Nginx是七層(反向代理)負載均衡器,他工作在第七層,即應用層。他發出去的包已經不是使用者的包了,使用者請求直接和反向代理執行的tcp3次握手。即為7層代理

(2)實現Nginx負載均衡的元件說明

實現Nginx負載均衡的元件主要有兩個,如下表: 
image_1crs8g5qk1j0042q1mmb1k16lni13.png-49.6kB

 

二、快速實踐Nginx負載均衡環境準備

image_1crs8hiqp1jnn1g6262crdgi2f1g.png-46.1kB

上圖中,所有使用者的請求統一發送到Nginx負載均衡器,然後由負載均衡器根據排程演算法來請求Web01和Web02

1、軟硬體準備 
三臺虛擬機器,兩臺做web,一臺做nginx,三臺虛擬機器都需要安裝nginx

2、安裝Nginx軟體,命令如下

 
  1. yum install -y pcre-devel openssl-devel #用本地yum倉庫安裝依賴包
  2. wget -q http://nginx.org/download/nginx-1.10.2.tar.gz #下載軟體原始碼包
  3. useradd -s /sbin/nologin -M www #建立程式使用者
  4. tar xf nginx-1.10.2.tar.gz -C /usr/src/ #解壓縮
  5. cd /usr/src/nginx-1.10.2
  6. ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module #預配置
  7. make && make install #編譯和安裝
  8. ln -s /usr/local/nginx/sbin/* /usr/local/sbin/ #給命令做軟連線,以便PATH能找到
  9. /usr/local/nginx/sbin/nginx #啟動nginx

加工Nginx配置檔案

 
  1. cd /usr/local/nginx/conf
  2. egrep -v "#|^$" nginx.conf.default > nginx.conf
  3. /usr/local/nginx/sbin/nginx -s reload #平滑重啟
  4. 以上Nginx就安裝完成了。

3、配置用於測試的Web服務

 
  1. [[email protected] conf]# cat nginx.conf
  2. worker_processes 1;
  3. events {
  4. worker_connections 1024;
  5. }
  6. http {
  7. include mime.types;
  8. default_type application/octet-stream;
  9. sendfile on;
  10. keepalive_timeout 65;
  11. log_format main '$remote_addr-$remote_user[$time_local]"$request"'
  12. '$status $body_bytes_sent "$http_referer"'
  13. '"$http_user_agent""$http_x_forwarded_for"'; #日誌格式化
  14. server {
  15. listen 80;
  16. server_name bbs.mendermi.com;
  17. location / {
  18. root html/bbs;
  19. index index.html index.htm;
  20. }
  21. access_log logs/access_bbs.log main; #應用格式化
  22. }
  23. server {
  24. listen 80;
  25. server_name www.mendermi.com;
  26. location / {
  27. root html/www;
  28. index index.html index.htm;
  29. }
  30. access_log logs/access_www.log main;
  31. }
  32. }
  33. #提示:
  34. 這裡故意將www虛擬主機放在下面,便於用後面的引數配置測試效果
  35. 配置檔案在Web1裡也寫一份

配置完成後檢查語法,並啟動Nginx服務

 
  1. [[email protected] conf]# nginx -t
  2. [[email protected] conf]# /usr/local/nginx/sbin/nginx -s reload
  3. [[email protected] conf]# netstat -antup | grep nginx
  4. tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 6760/nginx

然後填充測試檔案資料,如下:

 
  1. [[email protected] ~]# mkdir /usr/local/nginx/html/{www,bbs}
  2. [[email protected] ~]# echo "`hostname -I `www" >> /usr/local/nginx/html/www/index.html
  3. [[email protected] ~]# cat /usr/local/nginx/html/www/index.html
  4. 192.168.200.139 www
  5. [[email protected]~]# echo "`hostname -I `bbs" >> /usr/local/nginx/html/bbs/index.html
  6. [[email protected] ~]# cat /usr/local/nginx/html/bbs/index.html
  7. 192.168.200.139 bbs
  8. 以上同樣的命令在Web1上也執行一遍

配置解析Web和Web1的IP和主機名後,用curl測試一下

image_1crtoe2gbek7gdh1c171cq2gmi9.png-22.9kB

image_1crtofdhl111u1itn1vbg14p5bom.png-22.5kB

 

三、實現一個簡單的負載均衡

本服務在nginx伺服器操作

1、配置負載均衡,代理www.mendermi.com服務

 
  1. vim /usr/local/nginx/conf/nginx.conf
  2. worker_processes 1;
  3. events {
  4. worker_connections 1024;
  5. }
  6. http {
  7. include mime.types;
  8. default_type application/octet-stream;
  9. sendfile on;
  10. keepalive_timeout 65;
  11. upstream www_server_pools {
  12. server 192.168.200.135:80 weight=1;
  13. server 192.168.200.137:80 weight=1;
  14. }
  15. server {
  16. listen 80;
  17. server_name www.mendermi.com;
  18. location / {
  19. proxy_pass http://www_server_pools;
  20. }
  21. }
  22. }

image_1cru45j4jcp6172o14if1qb210m99.png-204.2kB

檢查語法並啟動

image_1crtpiotb14is7rkp0s1d5f165s20.png-12.8kB

檢查負載均衡測試結果。Linux作為客戶端的測試結果如下 
image_1crtpsnc25kf1qcaofeq436t92d.png-37.3kB

從上面的測試結果可以看出來。兩個Web節點按照1:1的比例被訪問。 下面宕掉任意一個Web節點,看看測試結果如何,測試如下:

例,關閉Web的nginx服務 
測試結果: 
image_1crtq66o61v251efj1p1u101pctn2q.png-31.2kB 
上圖可以看到,網站業務不受影響,訪問請求都定位到了正常的節點上。

例關閉所有Web的nginx服務 
測試結果: 
image_1crtr59sqc791eot1a2n16aai0r37.png-58.3kB 
上圖可以看到,Nginx代理下面沒有節點了,因此,Nginx向用戶報告了502錯誤。

開啟所有Web伺服器的nginx服務 
測試結果: 
image_1crtrcjhr13hcso7vgu1inm1omj3k.png-27.3kB 
結果是Nginx又把請求一比一分配到了Nginx後面的節點上。

 

四、Nginx負載均衡核心元件介紹

 

一、Nginx upstream模組

1 、upstream模組介紹 
Nginx的負載均衡功能依賴於ngx_http_upsteam_module模組,所支援的代理方式包括proxy_pass,fastcgi_pass,memcached_pass等,新版Nginx軟體支援的方式有所增加。我們實驗proxy_pass代理方式。 
ngx_http_upstream_module模組允許Nginx定義一組或多組節點伺服器組,使用時可以通過proxy_pass代理方式把網站的請求傳送到事先定義好的對應Upstream組的名字上,具體寫法為“proxy_pass http:// www_server_pools”,其中www_server_pools就是一個Upstream節點伺服器組名字。ngx_http_upstream_module模組官方地址為:http://nginx.org/en/docs/http/ngx_http_upstream_module.html

image_1cru5jl871980j8bigvq4458sm.png-64.9kB

image_1cru5k7fdtdftqh1kcr1meq1du313.png-70.3kB

2、upstream模組相關說明 
upstream模組的內容應放於nginx.conf配置的http{}標籤內,其預設排程節點演算法是wrr(weighted round-robin,即權重輪詢)。下圖為upstream模組內部server標籤部分引數說明
image_1cru5m7l410bust5e7kk591ri81g.png-297.3kB

image_1cru5p9ca1lir49ec5t18vf7k81t.png-101.1kB

上述命令的說明如下:

weight:調節伺服器的請求分配權重。 check:開啟對該伺服器健康檢查。 
inter:設定連續兩次的健康檢查間隔時間,單位毫秒,預設值2000 
rise:指定多少次連續成功的健康檢查後,即可認定該伺服器處於可用狀態。 
fall:指定多少次不成功的健康檢查後,即認為伺服器為宕機狀態,預設值3. maxconn:指定可被髮送到該伺服器的最大併發連線數。

3、upstream模組排程演算法 
排程演算法一般分為兩類: 
第一類為靜態排程演算法,即負載均衡器根據自身設定的規則進行分配,不需要考慮後端節點伺服器的情況,例如:rr,wrr,ip_hash等都屬於靜態排程演算法。 
第二類為動態排程演算法,即負載均衡器會根據後端節點的當前狀態來決定是否分發請求,例如:連線數少的優先獲得請求,響應時間短的優先獲得請求。例如:least_conn,fair等都屬於動態排程演算法。

下面介紹一下常見的排程演算法。

(1) rr輪詢(預設排程演算法,靜態排程演算法)

按客戶端請求順序把客戶端的請求逐一分配到不同的後端節點伺服器,這相當於LVS中的rr演算法,如果後端節點伺服器宕機(預設情況下Nginx只檢測80埠),宕機的伺服器會被自動從節點伺服器池中剔除,以使客戶端的使用者訪問不受影響。新的請求會分配給正常的伺服器。

(2)wrr(權重輪詢,靜態排程演算法)

在rr輪詢演算法的基礎上加上權重,即為權重輪詢演算法,當使用該演算法時,權重和使用者訪問成正比,權重值越大,被轉發的請求也就越多。可以根據伺服器的配置和效能指定權重值大小,有效解決新舊伺服器效能不均帶來的請求分配問題。

(3)ip_hash(靜態排程演算法)(會話保持)

每個請求按客戶端IP的hash結果分配,當新的請求到達時,先將其客戶端IP通過雜湊演算法雜湊出一個值,在隨後的客戶端請求中,客戶IP的雜湊值只要相同,就會被分配至同一臺伺服器,該排程演算法可以解決動態網頁的session共享問題,但有時會導致請求分配不均,即無法保證1:1的負載均衡,因為在國內大多數公司都是NAT上網模式,多個客戶端會對應一個外部IP,所以,這些客戶端都會被分配到同一節點伺服器,從而導致請求分配不均。LVS負載均衡的-p引數,Keepalived配置裡的persistence_timeout 50引數都類似這個Nginx裡的ip_hash引數,其功能都可以解決動態網頁的session共享問題。 
解決會話保持,1、ip hash 2、session共享 3、cookie

image_1cru5thod1dhg1svg18pv18hes5d2a.png-29kB

注意: 
當負載排程演算法為ip_hash時,後端伺服器在負載均衡排程中的狀態不能有weight和backup,即使有也不會生效。

(4)fair(動態排程演算法)

此演算法會根據後端節點伺服器的響應時間來分配請求,響應時間短的優先分配。這是更加智慧的排程演算法。此種演算法可以根據頁面大小和載入時間長短智慧地進行負載均衡,也就是根據後端伺服器的響應時間來分配請求,響應時間短的優先分配。Nginx本身不支援fair排程演算法,如果需要使用這種排程演算法,必須下載Nginx相關模組upstream_fair。

示例如下: 
image_1cru9uao8s7d18qh1e2cr041d3b2n.png-7.6kB

(5)least_conn

least_conn演算法會根據後端節點的連線數來決定分配情況,哪個機器連線數少就分發。 
除了上面介紹的這些演算法外,還有一些第三方排程演算法,例如:url_hash,一致性hash演算法等,介紹如下。

(6)url_hash演算法(web快取節點)

與ip_hash類似,這裡是根據訪問URL的hash結果來分配請求的,讓每個URL定向到同一個後端伺服器,後端伺服器為快取伺服器時效果顯著。在upstream中加入hash語句,server語句中不能寫入weight等其他的引數,hash_method使用的是hash演算法。 
url_hash按訪問URL的hash結果來分配請求,使每個URL定向到同一個後端伺服器,可以進一步提高後端快取伺服器的效率命令率。Nginx本身是不支援url_hash的,如果需要使用這種排程演算法,必須安裝Nginx的hash模組軟體包。

url_hash(web快取節點)和ip_hash(會話保持)類似。示例配置如下: 
image_1crua1qh01evn1luu1rs8lui1c4g34.png-9.3kB

(7)一致性hash演算法

一致性hash演算法一般用於代理後端業務為快取服務(如Squid,Memcached)的場景,通過將使用者請求的URI或者指定字串進行計算,然後排程到後端的伺服器上,此後任何使用者查詢同一個URI或者指定字串都會被排程到這一臺伺服器上,因此後端的每個節點快取的內容都是不同的,一致性hash演算法可以解決後端某個或幾個節點宕機後,快取的資料動盪最小,一致性hash演算法知識比較複雜,詳細內容可以參考百度上的相關資料,這裡僅僅給出配置示

例: 
image_1crua35oc1c4m1tdi1dbu1ctr1l5m3h.png-15.9kB

雖然Nginx本身不支援一致性hash演算法,但Nginx得分支Tengine支援。詳細可參考 
http://tengine.taobao.org/document_cn/http_upstream_consistent_hash_cn.html

 

二、 http_proxy_module模組

1、 proxy_pass指令介紹

proxy_pass指令屬於ngx_http_proxy_module模組,此模組可以將請求轉發到另一臺伺服器,在實際的反向代理工作中,會通過location功能匹配指定的URI,然後把接收到的符合匹配URI的請求通過proxy_pass拋給定義好的upstream節點池。該指令官方地址1見:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

image_1crubho08kfp1bps4631dfve4s4e.png-50.2kB

2、http proxy模組引數 
Nginx的代理功能是通過http proxy模組來實現的。預設在安裝Nginx時已經安裝了http proxy模組,因此可直接使用http proxy模組。下面詳細解釋模組1中每個選項代表的含義,見下表:

image_1crubjcjtirrb711orh1sqk1h594r.png-250.1kB

 

五、Nginx負載均衡配置實戰

 

一、Nginx負載均衡配置

  1. 檢視nginx的配置檔案如下:

    1. [[email protected] nginx]# cat /usr/local/nginx/conf/nginx.conf
    2. worker_processes 1;
    3. events {
    4. worker_connections 1024;
    5. }
    6. http {
    7. include mime.types;
    8. default_type application/octet-stream;
    9. sendfile on;
    10. keepalive_timeout 65;
    11. upstream www_server_pools {
    12. server 192.168.200.135:80 weight=1;
    13. server 192.168.200.137:80 weight=1;
    14. }
    15. server {
    16. listen 80;
    17. server_name www.mendermi.com;
    18. location / {
    19. proxy_pass http://www_server_pools;
    20. }
    21. }
    22. }

    image_1cs0ejepsdn9oupj2oftle9l9.png-81.3kB

在代理伺服器nginx上進行測試: 
image_1cs0em00t1iuk1q0e245hnt1trrm.png-24.7kB

從測試結果可以看出,已經實現了反向代理,負載均衡功能,但是有一個特殊問題,出來的結果並不是帶有www的字串,而是bbs的字串,根據訪問結果,我們推測是訪問了Web節點下bbs的虛擬主機,明明代理的是www虛擬主機,為什麼結果是訪問了後端的bbs虛擬主機了呢?問題又該如何解決?請同學們繼續往下看。

2、反向代理多虛擬主機節點伺服器企業案例

上一節代理的結果不對,究其原因是當用戶訪問域名時確實是攜帶了www.yunjisuan.com主機頭請求Nginx反向代理伺服器,但是反向代理向下面節點重新發起請求時,預設並沒有在請求頭裡告訴節點伺服器要找哪臺虛擬主機,所以,Web節點伺服器接收到請求後發現沒有主機頭資訊,因此,就把節點伺服器的第一個虛擬主機發給了反向代理了(節點上第一個虛擬主機放置的是故意這樣放置的bbs)。解決這個問題的方法,就是當反向代理向後重新發起請求時,要攜帶主機頭資訊,以明確告訴節點伺服器要找哪個虛擬主機。具體的配置很簡單,就是在Nginx代理www服務虛擬主機配置裡增加如下一行配置即可:

proxy_set_header host $host;

在代理向後端伺服器傳送的http請求頭中加入host欄位資訊後,若後端伺服器配置有多個虛擬主機,它就可以識別代理的是哪個虛擬主機。這是節點伺服器多虛擬主機時的關鍵配置。整個Nginx代理配置為:

 
  1. [[email protected] nginx]# cat /usr/local/nginx/conf/nginx.conf
  2. worker_processes 1;
  3. events {
  4. worker_connections 1024;
  5. }
  6. http {
  7. include mime.types;
  8. default_type application/octet-stream;
  9. sendfile on;
  10. keepalive_timeout 65;
  11. upstream www_server_pools {
  12. server 192.168.200.135:80 weight=1;
  13. server 192.168.200.137:80 weight=1;
  14. }
  15. server {
  16. listen 80;
  17. server_name www.mendermi.com;
  18. location / {
  19. proxy_pass http://www_server_pools;
  20. proxy_set_header host $host;
  21. }
  22. }
  23. }

image_1cs0f1jge4dd3gfaafnefelt13.png-70.9kB

在代理伺服器nginx上進行測試:

image_1cs0f4c32det1rpdq4l1rui1mre2g.png-25.5kB

上圖可以看到這次訪問的結果和訪問的域名就完全對應上了,這樣代理多虛擬主機的節點伺服器就不會出問題了

3、經過反向代理後的節點伺服器記錄使用者IP企業案例

完成了反向代理WWW服務後,節點伺服器對應的WWW虛擬主機的訪問日誌的第一個欄位記錄的並不是客戶端的IP,而是反向代理伺服器的IP,最後一個欄位也是“-”!

例如:使用任意windows客戶端計算機,訪問已經解析好代理IP的www.yunjisuan.com後,去節點伺服器www服務日誌檢視,就會發現如下日誌:

 
  1. [[email protected] logs]# cat access_www.log
  2. 192.168.200.139--[11/Nov/2018:21:26:01 +0800]"GET / HTTP/1.0"200 20 "-""Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko""-"

Web1節點伺服器對應的WWW虛擬主機的訪問日誌的第一個欄位記錄的並不是客戶端的IP而是反向代理伺服器本身的IP(192.168.0.221),最後一個欄位也是一個“-”,那麼如何解決這個問題?其實很簡單,同樣是增加如下一行引數:

 
  1. proxy_set_header X-Forwarded-For $remote_addr;
  2. #這是反向代理時,節點伺服器獲取使用者真實IP的必要功能配置

在反向代理請求後端節點伺服器的請求頭中增加獲取的客戶端IP的欄位資訊,然後節點後端可以通過程式或者相關的配置接收X-Forwarded-For傳過來的使用者真實IP的資訊。