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

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

課堂筆記html


 

1、原理

 

1.1 爲何要使用集羣

(1)高性能前端

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

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

(2)價格有效性算法

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

當服務負載,壓力增加時,針對集羣系統進行較簡單的擴展便可知足需求,且不會下降服務質量。編程

一般狀況下,硬件設備若想擴展性能,不得不增長新的CPU和存儲器設備,若是加不上去了,就不得不夠買更高性能的服務器,就拿咱們如今的服務器來說,能夠增長的設備老是有限的。若是採用集羣技術,則只須要將新的單個服務器加入現有集羣架構中便可,從訪問的客戶角度來看,系統服務不管是連續性仍是性能上都幾乎沒有變化,系統在不知不覺中完成了升級,加大了訪問能力,輕鬆地實現了擴展。集羣系統中的節點數目能夠增加到幾千乃至上萬個,其伸縮性遠超過單臺超級計算機。vim

(4)高可用性windows

單一的計算機系統總會面臨設備損毀的問題,如CPU,內存,主板,電源,硬盤等,只要一個部件壞掉,這個計算機系統就可能會宕機,沒法正常提供服務。在集羣系統中,儘管部分硬件和軟件也仍是會發生故障,但整個系統的服務能夠是7*24小時可用的。 
集羣架構技術可使得系統在若干硬件設備故障發生時仍能夠繼續工做,這樣就將系統的停機時間減小到了最小。集羣系統在提升系統可靠性的同時,也大大減少了系統故障帶來的業務損失,目前幾乎100%的互聯網網站都要求7*24小時提供服務。 
(5)透明性
後端

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

(6)可管理性

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

(7)可編程性

在集羣系統上,容易開發及修改各種應用程序。

 

1.二、集羣的常見分類

計算機集羣架構按功能和結構能夠分紅如下幾類: 
一、負載均衡集羣,簡稱LBC或者LB 
二、高可用性集羣,簡稱HAC 
三、高性能計算集羣,簡稱HPC 
四、網格計算集羣 
五、負載均衡集羣和高可用性集羣是互聯網行業經常使用的集羣架構模式

 

1.三、不一樣種類的集羣介紹

一、負載均衡集羣

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

(1)負載均衡集羣的做用爲:

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

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

二、高可用性集羣

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

高可用性集羣的做用爲: 
當一臺機器宕機時,另一臺機器接管宕機的機器的IP資源和服務資源,提供服務。 
經常使用於不易實現負載均衡的應用,好比負載均衡器,主數據庫,主存儲對之間。 
高可用性集羣經常使用的開源軟件包括Keepalived,Heartbeat等,其架構圖以下圖所示: 
image_1crs80p9u183vadkjrvd3p1dusm.png-214.9kB

三、高性能計算集羣

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

在互聯網網站運維中,比較經常使用的就是負載均衡集羣和高可用性集羣

 

1.四、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.五、Nginx負載均衡集羣介紹

一、搭建負載均衡服務的需求 
負載均衡集羣提供了一種廉價,有效,透明的方法,來擴展網絡設備和服務器的負載,帶寬和吞吐量,同時增強了網絡數據處理能力,提升了網絡的靈活性和可用性。

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

(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

 

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

image_1crs8hiqp1jnn1g6262crdgi2f1g.png-46.1kB

上圖中,全部用戶的請求統一發送到Nginx負載均衡器,而後由負載均衡器根據調度算法來請求Web01和Web02

一、軟硬件準備 
三臺虛擬機,兩臺作web,一臺作nginx,三臺虛擬機都須要安裝nginx

二、安裝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就安裝完成了。

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

 
  1. [root@Web 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. [root@Web conf]# nginx -t
  2. [root@Web conf]# /usr/local/nginx/sbin/nginx -s reload
  3. [root@Web conf]# netstat -antup | grep nginx
  4. tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 6760/nginx

而後填充測試文件數據,以下:

 
  1. [root@Web ~]# mkdir /usr/local/nginx/html/{www,bbs}
  2. [root@Web ~]# echo "`hostname -I `www" >> /usr/local/nginx/html/www/index.html
  3. [root@Web ~]# cat /usr/local/nginx/html/www/index.html
  4. 192.168.200.139 www
  5. [root@Web~]# echo "`hostname -I `bbs" >> /usr/local/nginx/html/bbs/index.html
  6. [root@Web ~]# 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

 

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

本服務在nginx服務器操做

一、配置負載均衡,代理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後面的節點上。

 

4、Nginx負載均衡核心組件介紹

 

1、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

二、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:指定可被髮送到該服務器的最大併發鏈接數。

三、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共享問題。 
解決會話保持,一、ip hash 二、session共享 三、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

 

2、 http_proxy_module模塊

一、 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

二、http proxy模塊參數 
Nginx的代理功能是經過http proxy模塊來實現的。默認在安裝Nginx時已經安裝了http proxy模塊,所以可直接使用http proxy模塊。下面詳細解釋模塊1中每一個選項表明的含義,見下表:

image_1crubjcjtirrb711orh1sqk1h594r.png-250.1kB

 

5、Nginx負載均衡配置實戰

 

1、Nginx負載均衡配置

  1. 查看nginx的配置文件以下:

    1. [root@nginx 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虛擬主機了呢?問題又該如何解決?請同窗們繼續往下看。

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

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

proxy_set_header host $host;

在代理向後端服務器發送的http請求頭中加入host字段信息後,若後端服務器配置有多個虛擬主機,它就能夠識別代理的是哪一個虛擬主機。這是節點服務器多虛擬主機時的關鍵配置。整個Nginx代理配置爲:

 
  1. [root@nginx 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

上圖能夠看到此次訪問的結果和訪問的域名就徹底對應上了,這樣代理多虛擬主機的節點服務器就不會出問題了

三、通過反向代理後的節點服務器記錄用戶IP企業案例

完成了反向代理WWW服務後,節點服務器對應的WWW虛擬主機的訪問日誌的第一個字段記錄的並非客戶端的IP,而是反向代理服務器的IP,最後一個字段也是「-」!

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

 
  1. [root@Web1 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的信息。

image_1cs0k45tem3ig094hj1lc71tbg3q.png-67.3kB

從新加載Nginx反向代理服務:[root@nginx nginx]# nginx -s reload 
微信圖片_20181111133652.png-41.7kB

測試檢查 
image_1cs0keh66jt61o9i1iui114upvm6r.png-11kB 
image_1cs0keuf81q2gc541vj19rtqth78.png-10.9kB

去節點服務器WWW服務的訪問日誌裏查看,會發現日誌的結尾已經變化了: 
微信圖片_20181111133958.png-10.5kB
此時尾部信息因爲咱們虛擬機是NAT模式,因此顯示的是NAT的網關。

其中,日誌裏的192.168.200.139爲反向代理的IP,對應Nginx日誌格式裏的變量,而日誌結尾的對應的時日誌格式裏的http_x_forwarded_for」變量,即接收了前面反向代理配置中「proxy_set_header 
X-Forwarded-For $remote_addr;」參數X-Forwarded-For的IP了。 
關於X-Forwarded-For的詳細說明,可見http://en.wikipedia.org/wiki/X-Forwwawrded-For。下圖是反向代理相關重要基礎參數的總結,供參考。

image_1cs0kool9nff7oq14o4j254k696.png-138.6kB

 

2、與反向代理配置相關的更多參數說明

除了具備多虛擬主機代理以及節點服務器記錄真實用戶IP的功能外,Nginx軟件還提供了至關多的做爲反向代理和後端節點服務器對話的相關控制參數,具體見前面proxy模塊時提供的圖表。

一、因爲參數衆多,最好把這些參數放到一個配置文件裏,而後用include方式包含到虛擬主機配置裏,效果以下: 
image_1cs0l6l7j24lvlk1atj8hi1kp79j.png-45.4kB

image_1cs0lgufh1p5n3l5b9791m5qad.png-29.8kB

 

6、根據URL中的目錄地址實現代理轉發

一、例:經過Nginx實現動靜分離,即經過Nginx反向代理配置規則實現讓動態資源和靜態資源及其餘業務分別由不一樣的服務器解析,以解決網站性能,安全,用戶體驗等重要問題。

下圖爲企業常見的動靜分離集羣架構圖,此架構圖適合網站前端只使用同一個域名提供服務的場景,例如,用戶訪問的域名是www.mendermi.com,而後,當用戶請求www.mendermi.com/upload/xx地址時候,代理會分配請求到上傳服務器池處理數據;當用戶請求www.mendermi.com/static/xx地址的時候,代理會分配請求到靜態服務器池請求數據;當用戶請求www.mendermi.com/xx地址的時候,即不包含上述指定的目錄地址路徑時,代理會分配請求到默認的動態服務器池請求數據(注意:上面的xx表示任意路徑)。

image_1cs0nqhe1rn4dgg1eb210nq76qaq.png-137.7kB

二、準備:配置實戰

需求梳理: 
- 當用戶請求www.mendermi.com/upload/xx地址時,實現由upload上傳服務器池處理請求。 
- 當用戶請求www.mendermi.com/static/xx地址時,實現由靜態服務器池處理請求。 
- 除此之外,對於其餘訪問請求,全都由默認的動態服務器池處理請求。

瞭解了需求後,就能夠進行upstream模塊服務器池的配置了。

 
  1. #static_pools爲靜態服務器池,有一個服務器,地址爲192.168.200.135,端口爲80.
  2. upstream static_pools {
  3. server 192.168.200.135:80 weght=1;
  4. }
  5. #upload_pools爲上傳服務器池,有一個服務器地址爲192.168.200.137,端口爲80.
  6. upstream upload_pools {
  7. server 192.168.200.137:80 weight=1;
  8. }
  9. #default_pools爲默認的服務器池,即動態服務器池,有一個服務器,地址爲192.168.200.128,端口爲80.
  10. upstream default_pools {
  11. server 192.168.200.128:80 weight=1;
  12. }
  13. #提示:須要增長一臺測試Web節點Web03(ip:192.168.200.128),配置與Web01,Web02同樣。

下面利用location或if語句把不一樣的URI(路徑)請求,分給不一樣的服務器池處理,具體配置以下。 
方案1:以location方案實現

 
  1. #將符合static的請求交給靜態服務器池static_pools,配置以下:
  2. location /static/ {
  3. proxy_pass http://static_pools;
  4. include proxy.conf;
  5. }
  6. #將符合upload的請求交給上傳服務器池upload_pools,配置以下:
  7. location /upload/ {
  8. proxy_pass http://upload_pools;
  9. include proxy.conf;
  10. }
  11. #不符合上述規則的請求,默認所有交給動態服務器池default_pools,配置以下:
  12. location / {
  13. proxy_pass http://default_pools;
  14. include proxy.conf;
  15. }

方案2:以if語句實現。

 
  1. if ($request_uri ~* "^/static/(.*)$")
  2. {
  3. proxy_pass http://static_pools/$1;
  4. }
  5. if ($request_uri ~* "^/upload/(.*)$")
  6. {
  7. proxy_pass http://upload_pools/$1;
  8. }
  9. location / {
  10. proxy_pass http://default_pools;
  11. include proxy.conf;
  12. }

下面以方案1爲例進行實驗,Nginx反向代理的實際配置以下:

 
  1. [root@nginx nginx]# cat 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 static_pools {
  12. server 192.168.200.135:80 weight=1;
  13. }
  14. upstream upload_pools {
  15. server 192.168.200.137:80 weight=1;
  16. }
  17. upstream default_pools {
  18. server 192.168.200.128:80 weight=1;
  19. }
  20. server {
  21. listen 80;
  22. server_name www.mendermi.com;
  23. location / {
  24. proxy_pass http://default_pools;
  25. include proxy.conf;
  26. }
  27. location /static/ {
  28. proxy_pass http://static_pools;
  29. include proxy.conf;
  30. }
  31. location /upload/ {
  32. proxy_pass http://upload_pools;
  33. include proxy.conf;
  34. }
  35. }
  36. }

從新加載配置生效 
image_1cs0pokeg17nk13iv167r11851c1sb7.png-17.5kB

暫時不要馬上測試成果,爲了實現上述代理的測試,還須要在Web01和Web02上作節點的測試配置,才能更好地展現測試效果。 
以Web1做爲static靜態服務,地址端口爲:192.168.200.135:80,須要事先配置一個用於測試靜態的地址頁面,並測試訪問,肯定它會返回正確結果。操做步驟以下:

 
  1. [root@Web1 html]# cd www/
  2. [root@Web1 www]# mkdir static
  3. [root@Web1 www]# echo "static_pools" >> static/index.html
  4. [root@Web1 www]# curl http://www.mendermi.com/static/index.html
  5. static_pools

image_1cs0q5h0m1jtef0k1i18i15l7nbk.png-35kB

以Web2做爲upload上傳服務,地址端口爲:192.168.200.137:80,須要事先配置一個用於測試上傳服務的地址頁面,並測試訪問,肯定它會返回正確結果。建立目錄及文件同Web1類似,只是改了模塊名,詳見下圖

image_1cs0qgop31s0k1v1lpa0hn318r5ce.png-16.1kB

image_1cs0qepif1q7dlu313icipq173vc1.png-22.1kB

在Web3做爲動態服務節點,地址端口爲192.168.200.128:80,一樣須要事先配置一個默認的地址頁面,並測試訪問,肯定它會返回正確結果。操做步驟以下:

 
  1. [root@web3 www]# cd /usr/local/nginx/html/www
  2. [root@web3 www]# echo "default_pools" >> index.html
  3. [root@web3 www]# curl http://www.yunjisuan.com
  4. default_pools

image_1cs0qq3oncqkd4dc5luhq1d5vcr.png-5.4kB

以上準備了三臺Web節點服務器,分別加入到了upstream定義的不一樣服務器池,表明三組不一樣的業務集羣組,從本機經過hosts解析各自的域名,而後測試訪問,其地址與實際訪問的內容輸出請對照下表:

image_1cs0rr3fk1eob160p1al01085gs513.png-22kB

使用客戶端計算機訪問測試時,最好選用集羣之外的機器,這裏先在瀏覽器客戶端的hosts文件裏把www.yunjisuan.com解析到Nginx反向代理服務器的IP,而後訪問上述URL,看代理是否是把請求正確地轉發到了指定的服務器上。若是能夠獲得與上表對應的內容,表示配置的Nginx代理分發的徹底正確,由於若是分發請求到錯誤的機器上就沒有對應的URL頁面內容,輸出會是404錯誤。

image_1cs0rtnov3a63bm42r1r6d6831g.png-11.7kB

image_1cs0rugib1vj31nvv11fs1dv716kc1t.png-11.3kB

image_1cs0rvdi6duq1n0r17n1q5f77t2q.png-10.7kB 以上測試成功!

相關文章
相關標籤/搜索