Nginx反向代理與負載均衡

Nginx反向代理與負載均衡

 

集羣簡介

簡單地說,集羣就是指一組(若干個)相互獨立的計算機,利用高速通訊網絡組成的一個較大的計算機服務系統,每一個集羣節點(即集羣中的每臺計算機)都是運行各自服務的獨立服務器。這些服務器之間能夠彼此通訊,協同向用戶提供應用程序,系統資源和數據,並以單一系統的模式加以管理。當用戶客戶機請求集羣系統時,集羣給用戶的感受就是一個單一獨立的服務器,而實際上用戶請求的是一組集羣服務器。php

打開谷歌,百度的頁面,看起來好簡單,也許你以爲用幾分鐘就能夠製做出類似的網頁,而實際上,這個頁面的背後是由成千上萬臺服務器集羣協同工做的結果。而這麼多的服務器維護和管理,以及相互協調工做也許就是同窗們將來的工做職責了。html

若要用一句話描述集羣,即一堆服務器合做作同一件事,這些機器可能須要整個技術團隊架構,設計和統一協調管理,這些機器能夠分佈在一個機房,也能夠分佈在全國全球各個地區的多個機房。前端

 

爲何要使用集羣

(1)高性能nginx

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

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

集羣高性能。.png-273.6kB

(2)價格有效性數據庫

一般一套系統集羣架構,只須要幾臺或數十臺服務器主機便可。與動輒價值上百萬元的專用超級計算機相比便宜了不少。在達到一樣性能需求的條件下,採用計算機集羣架構比採用同等運算能力的大型計算機具備更高的性價比。編程

早期的淘寶,支付寶的數據庫等核心系統就是使用上百萬元的小型機服務器。後因使用維護成本過高以及擴展設備費用成幾何級數翻倍,甚至成爲擴展瓶頸,人員維護也十分困難,最終使用PC服務器集羣替換之,好比,把數據庫系統從小機結合Oracle數據庫遷移到MySQL開源數據庫結合PC服務器上來。不但成本降低了,擴展和維護也更容易了。vim

(3)可伸縮性windows

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

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

(4)高可用性

單一的計算機系統總會面臨設備損毀的問題,如CPU,內存,主板,電源,硬盤等,只要一個部件壞掉,這個計算機系統就可能會宕機,沒法正常提供服務。在集羣系統中,儘管部分硬件和軟件也仍是會發生故障,但整個系統的服務能夠是7*24小時可用的。

集羣架構技術可使得系統在若干硬件設備故障發生時仍能夠繼續工做,這樣就將系統的停機時間減小到了最小。集羣系統在提升系統可靠性的同時,也大大減少了系統故障帶來的業務損失,目前幾乎100%的互聯網網站都要求7*24小時提供服務。

(5)透明性

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

(6)可管理性

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

(7)可編程性

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

 

集羣的常見分類

負載均衡集羣,簡稱LBC或者LB

高可用性集羣,簡稱HAC --->預防單點也就是高可用

高性能計算集羣,簡稱HPC

網格計算集羣

負載均衡集羣和高可用性集羣是互聯網行業經常使用的集羣架構模式,也是咱們要學習的重點。

 

負載均衡集羣的做用

分攤用戶訪問請求及數據流量(負載均衡)

保持業務連續性,即7*24小時服務(高可用性)

應用於Web業務及數據庫從庫等服務器的業務

負載均衡集羣典型的開源軟件包括LVS,Nginx,Haproxy等,以下圖所示

負載均衡集羣。.png-200.1kB

 

負載均衡集羣介紹

負載均衡集羣爲企業提供了更爲實用,性價比更高的系統架構解決方案。負載均衡集羣能夠把不少客戶集中的訪問請求負載壓力盡量平均地分攤在計算機集羣中處理。客戶訪問請求負載一般包括應用程序處理負載和網絡流量負載。這樣的系統很是適合使用同一組應用程序爲大量用戶提供服務的模式,每一個節點均可以承擔必定的訪問請求負載壓力,而且能夠實現訪問請求在各節點之間動態分配,以實現負載均衡。

負載均衡集羣運行時,通常是經過一個或多個前端負載均衡器將客戶訪問請求分發到後端的一組服務器上,從而達到整個系統的高性能和高可用性。通常高可用性集羣和負載均衡集羣會使用相似的技術,或同時具備高可用性與負載均衡的特色。

 

高可用性集羣的做用

當一臺機器宕機時,另一臺機器接管宕機的機器的IP資源和服務資源,提供服務。

經常使用於不易實現負載均衡的應用,好比負載均衡器,主數據庫,主存儲對之間。

高可用性集羣經常使用的開源軟件包括Keepalived,Heartbeat等,其架構圖以下圖所示

高可用性集羣。.png-205.4kB

 

高可用性集羣介紹

通常是指在集羣中任意一個節點失效的狀況下,該節點上的全部任務會自動轉移到其餘正常的節點上。此過程並不影響整個集羣的運行。

當集羣中的一個節點系統發生故障時,運行着的集羣服務會迅速做出反應,將該系統的服務分配到集羣中其餘正在工做的系統上運行。考慮到計算機硬件和軟件的容錯性,高可用性集羣的主要目的是使集羣的總體服務儘量可用。若是高可用性集羣中的主節點發生了故障,那麼這段時間內將由備節點代替它。備節點一般是主節點的鏡像。當它代替主節點時,它能夠徹底接管主節點(包括IP地址及其餘資源)提供服務,所以,使集羣系統環境對於用戶來講是一致的,既不會影響用戶的訪問。

高可用性集羣使服務器系統的運行速度和響應速度會盡量的快。他們常常利用在多臺機器上運行的冗餘節點和服務來相互跟蹤。若是某個節點失敗,它的替補者將在幾秒鐘或更短期內接管它的職責。所以,對於用戶而言,集羣裏的任意一臺機器宕機,業務都不會受影響(理論狀況下)。

 

Nginx負載均衡集羣介紹

 

搭建負載均衡服務的需求

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

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

(1)把單臺計算機沒法承受的大規模併發訪問或數據流量分擔到多臺節點設備上,分別進行處理,減小用戶等待響應的時間,提高用戶體驗。

(2)單個重負載的運算分擔到多臺節點設備上作並行處理,每一個節點設備處理結束後,將結果彙總,返回給用戶,系統處理能力獲得大幅度提升。

(3)7*24小時的服務保證,任意一個或多個有限後面節點設備宕機,不能影響業務。

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

 

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

 

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

嚴格地說,Nginx僅僅是做爲Nginx Proxy反向代理使用的,由於這個反向代理功能表現的效果是負載均衡集羣的效果,因此本文稱之爲Nginx負載均衡。那麼,反向代理和負載均衡有什麼區別呢?

普通負載均衡軟件,例如大名鼎鼎的LVS,其實功能只是對請求數據包的轉發(也可能會改寫數據包),傳遞,其中DR模式明顯的特徵是從負載均衡下面的節點服務器來看,接收到的請求仍是來自訪問負載均衡器的客戶端的真實用戶,而反向代理就不同了,反向代理接收訪問用戶的請求後,會代理用戶從新發起請求代理下的節點服務器,最後把數據返回給客戶端用戶,在節點服務器看來,訪問的節點服務器的客戶端用戶就是反向代理服務器了,而非真實的網站訪問用戶。

一句話,LVS等的負載均衡是轉發用戶請求的數據包,而Nginx反向代理是接收用戶的請求而後從新發起請求去請求其後面的節點。

Nginx是七層結構的,經過nginx自己來轉發,能夠有多種方式進行負載均衡,實現的功能多,nginx能夠分業務

LVS是四層結構的,經過轉發數據包mac或ip頭部,不能對數據進行修改,來實現的負載均衡,實現的功能少但效率高,LVS的WEB內容都給是同樣的

 

實現Nginx負載均衡的組件主要有兩個,以下表

負債均衡組件。.png-45.9kB

 

反向代理與負載均衡搭建

 

硬件準備

準備3臺VM虛擬機(有物理服務器更佳)都須要安裝Nginx服務

Nginx反向代理

NginxWebA

NginxWebB

image_1crp57ne91mjek0c1q9v1js41iahs.png-6.8kB

 

安裝依賴軟件包

yum -y install openssl openssl-devel pcre pcre-devel

rpm -qa openssl openssl-devel pcre pcre-devel

三臺都須要安裝支持包

image_1crp58vobfo7pno7v71usl9pq19.png-20.2kB

 

軟件包準備

nginx-1.10.2.tar.gz

image_1crp5ad1rtscc221q9v1hm51j9v1m.png-10.5kB

 

安裝Nginx服務

useradd -M -s /sbin/nologin nginx

tar xf nginx-1.10.2.tar.gz -C /usr/src

cd /usr/src/nginx-1.10.2

./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module && make && make install

ln -s /usr/local/nginx/sbin/* /usr/local/sbin/ --->軟連接可作可不作

egrep -v "#|^$" nginx.conf.default > nginx.conf --->把配置文件多餘的東西過濾掉

這裏只編譯了一個截圖,三臺虛擬機的步驟都是同樣的

image_1crp6k368e75d611ho2oud9mm9.png-51.9kB

 

簡單的Nginx反向代理配置文件

 
  1. worker_processes 1;
  2. events {
  3. worker_connections 1024;
  4. }
  5. http {
  6. include mime.types;
  7. default_type application/octet-stream;
  8. sendfile on;
  9. keepalive_timeout 65;
  10. upstream www_server {
  11. server 192.168.200.68:80 weight=1;
  12. server 192.168.200.69:80 weight=1;
  13. }
  14. server {
  15. listen 80;
  16. server_name sl.yunjisuan.com;
  17. location / {
  18. proxy_pass http://www_server;
  19. }
  20. }
  21. }
 

配置文件詳解

 
  1. #這裏定義Web服務器池,包含了68,69兩個Web節點
  2. upstream --->服務器池
  3. www_server --->是服務器池的名字
  4. server --->就是一個RS節點
  5. weight --->權重,負載均衡是按照權重比分配的
  6. #這裏定義代理的負載均衡域名虛擬主機
  7. proxy_pass --->訪問sl.yunjisuan.com,請求發送給www_server裏面的
 

WEBA配置文件

 
  1. worker_processes 1;
  2. events {
  3. worker_connections 1024;
  4. }
  5. http {
  6. include mime.types;
  7. default_type application/octet-stream;
  8. sendfile on;
  9. keepalive_timeout 65;
  10. server_tokens off;
  11. server {
  12. listen 80;
  13. server_name bbs.yunjisuan.com;
  14. location / {
  15. root html/bbs;
  16. index index.html index.htm;
  17. }
  18. }
  19. server {
  20. listen 80;
  21. server_name sl.yunjisuan.com;
  22. location / {
  23. root html/sl;
  24. index index.html index.htm;
  25. }
  26. }
  27. }

WEBB跟WEBA配置文件是同樣的

 

填充測試文件

 
  1. mkdir /usr/local/nginx/html/{sl,bbs}
  2. echo "`hostname -I ` sl" >> /usr/local/nginx/html/sl/index.html
  3. echo "`hostname -I ` bbs" >> /usr/local/nginx/html/bbs/index.html

WEBB跟WEBA測試文件是同樣的

 

添加WEB-A和B虛擬機本地映射

vim /etc/hosts

cat /etc/hosts

image_1crrauh48kkq1ke212k313vu1ftc1p.png-19.5kB

image_1crrauu0c19j9mhh16q4q083h726.png-19.6kB

 

配置完兩臺WEB服務器用curl測試一下

curl sl.yunjisuan.com

curl bbs.yunjisuan.com

image_1crrb5917g3d14li1hhk1k9065l2j.png-16.3kB

image_1crrb5n6nf1b1bh4jj1bqj22m3g.png-16.9kB

 

檢查兩臺WEB簡單的負載均衡測試結果

curl sl.yunjisuan.com

測試結果能夠看出來。兩個Web節點按照1:1的比例被訪問

image_1crrbvs7i1lm79udopc1ti81p553t.png-32.8kB

 

Nginx 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

 

基本的upstream配置案例

 
  1. upstream www_server_pools {
  2. # upstream是關鍵字必須有,後面的www_server_pools爲一個Upstream集羣組的名字,能夠本身起名,調用時就用這個名字
  3. server 192.168.0.223:80 weight=5;
  4. server 192.168.0.224:80 weight=10;
  5. server 192.168.0.225:80 weight=15;
  6. # server關鍵字是固定的,後面能夠接域名(門戶會用)或IP。若是不指定端口,默認是80端口。weight表明權重,數值越大被分配的請求越多,結尾有分號,別忘了。
  7. }
 

較完整的upstream配置案例

 
  1. upstream blog_server_pool {
  2. server 192.168.0.223; #這行標籤和下行是等價的
  3. server 192.168.0.224:80 weight=1 max_fails=1 fail_timeout=10s; #這行標籤和上一行是等價的,此行多餘的部分就是默認配置,不寫也能夠。
  4. server 192.168.0.225:80 weight=1 max_fails=2 fail_timeout=20s backup;
  5. # server最後面能夠加不少參數,具體參數做用看下文的表格
  6. }
 

使用域名及socket的upstream配置案例

 
  1. upstream backend {
  2. server backend1.example.com weight=5;
  3. server backend2.example.com:8080; #域名加端口。轉發到後端的指定端口上
  4. server unix:/tmp/backend3; #指定socket文件
  5. #提示:server後面若是接域名,須要內網有DNS服務器或者在負載均衡器的hosts文件作域名解析。
  6. server 192.168.0.223;
  7. server 192.168.0.224:8080;
  8. server backup1.example.com:8080 backup;
  9. #備份服務器,等上面指定的服務器都不可訪問的時候會啓動,backup的用法和Haproxy中用法同樣
  10. server backup2.example.com:8080 backup;
  11. }
 

權重比測試

 
  1. worker_processes 1;
  2. events {
  3. worker_connections 1024;
  4. }
  5. http {
  6. include mime.types;
  7. default_type application/octet-stream;
  8. sendfile on;
  9. keepalive_timeout 65;
  10. upstream www_server {
  11. server 192.168.200.68:80 weight=5;
  12. server 192.168.200.69:80 weight=1;
  13. }
  14. server {
  15. listen 80;
  16. server_name sl.yunjisuan.com;
  17. location / {
  18. proxy_pass http://www_server;
  19. }
  20. }
  21. }

測試階段多少會有點延遲,全部顯示的會不太準確

image_1crrid56v1apt15b861qrg6dtc8k.png-64.5kB

 

backup備份測試

 
  1. worker_processes 1;
  2. events {
  3. worker_connections 1024;
  4. }
  5. http {
  6. include mime.types;
  7. default_type application/octet-stream;
  8. sendfile on;
  9. keepalive_timeout 65;
  10. upstream www_server {
  11. server 192.168.200.68:80 weight=1 backup;
  12. server 192.168.200.69:80 weight=1;
  13. }
  14. server {
  15. listen 80;
  16. server_name sl.yunjisuan.com;
  17. location / {
  18. proxy_pass http://www_server;
  19. }
  20. }
  21. }

image_1crriptk41a25150i3lm834ba9h.png-40.7kB

image_1crriq7ua4ig1pped9rg7j1brs9u.png-14.5kB

 

特別提示

若是是兩臺Web服務器作高可用,常規方案就須要keepalived配合,那麼這裏使用Nginx的backup參數經過負載均衡功能就能夠實現Web服務器集羣了,對於企業應用來講,能作集羣就不作高可用。

 

upstream模塊相關說明

upstream模塊的內容應放於nginx.conf配置的http{}標籤內,其默認調度節點算法是wrr(weighted round-robin,即權重輪詢)。下圖爲upstream模塊內部server標籤部分參數說明

image_1crrd4dae1loa19ok1h1el1815cm4a.png-433.8kB

提示: 
以上參數與專業的Haproxy參數很相似,但不如Haproxy的參數易懂。

 

示例,以下

 
  1. upstream backend {
  2. server backend1.example.com weight=5; #若是就是單個Server,不必設置權重
  3. server 127.0.0.1:8080 max_fail=5 fail_timeout=10s;
  4. #當檢測次數等於5的時候,5次連續檢測失敗後,間隔10s再從新檢測。
  5. server unix:/tmp/backend3;
  6. server backup1.example.com:8080 backup; #熱備機器設置
  7. }
 

hash算法訪問

 
  1. upstream backend {
  2. ip_hash;
  3. server backend1.example.com;
  4. server backend2.example.com;
  5. server backend3.example.com down;
  6. server backend4.example.com;
  7. }

須要特別說明的是,若是是Nginx代理Cache服務,可能須要使用hash算法,此時若宕機,可經過設置down參數確保客戶端用戶按照當前的hash算法訪問,這一點很重要

 

開啓對後端服務器的健康檢測

 
  1. #開啓對後端服務器的健康檢測,經過GET /test/index.php來判斷後端服務器的健康狀況
  2. server php_server_1 192.168.0.223:80 cookie 1 check inter 2000 rise 3 fall 3 weight 2
  3. server php_server_2 192.168.0.224:80 cookie 2 check inter 2000 rise 3 fall 3 weight 1
  4. server php_server_bak 192.168.0.225:80 cookie 3 check inter 1500 rise 3 fall 3 backup
 

健康檢測命令詳解

 
  1. weight:調節服務器的請求分配權重。
  2. check:開啓對該服務器健康檢查。
  3. inter:設置連續兩次的健康檢查間隔時間,單位毫秒,默認值2000
  4. rise:指定多少次連續成功的健康檢查後,便可認定該服務器處於可用狀態。
  5. fall:指定多少次不成功的健康檢查後,即認爲服務器爲宕機狀態,默認值3.
  6. 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時,後端服務器在負載均衡調度中的狀態不能有weight和backup,即便有也不會生效。

 
  1. upstream yunjisuan_lb{
  2. ip_hash;
  3. server 192.168.0.223:80;
  4. server 192.168.0.224:8080;
  5. }
  6. upstream backend{
  7. ip_hash;
  8. server backend1.example.com;
  9. server backend2.example.com;
  10. server backend3.example.com down;
  11. server backend4.example.com;
  12. }

(4)fair(動態調度算法)

此算法會根據後端節點服務器的響應時間來分配請求,響應時間短的優先分配。這是更加智能的調度算法。此種算法能夠根據頁面大小和加載時間長短智能地進行負載均衡,也就是根據後端服務器的響應時間來分配請求,響應時間短的優先分配。Nginx自己不支持fair調度算法,若是須要使用這種調度算法,必須下載Nginx相關模塊upstream_fair。

 
  1. upstream yunjisuan_lb{
  2. server 192.168.0.223;
  3. server 192.168.0.224;
  4. fair;
  5. }

(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模塊軟件包。

 
  1. upstream yunjisuan_lb {
  2. server squid1:3128;
  3. server squid2:3128;
  4. hash $request_uri;
  5. hash_method crc32;
  6. }

(7)一致性hash算法(Nginx沒有)

一致性hash算法通常用於代理後端業務爲緩存服務(如Squid,Memcached)的場景,經過將用戶請求的URI或者指定字符串進行計算,而後調度到後端的服務器上,此後任何用戶查找同一個URI或者指定字符串都會被調度到這一臺服務器上,所以後端的每一個節點緩存的內容都是不一樣的,一致性hash算法能夠解決後端某個或幾個節點宕機後,緩存的數據動盪最小,一致性hash算法知識比較複雜,詳細內容能夠參考百度上的相關資料,這裏僅僅給出配置示例

 
  1. http {
  2. upstream test {
  3. consistent_hash $request_uri;
  4. server 127.0.0.1:9001 id=1001 weight=3;
  5. server 127.0.0.1:9002 id=1002 weight=10;
  6. server 127.0.0.1:9003 id=1003 weight=20;
  7. }
  8. }

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

 

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

 

proxy_pass的使用案例

(1)將匹配URI爲name的請求拋給http://127.0.0.1/remote/

 
  1. location /name/ {
  2. proxy_pass http://127.0.0.1/remote/;
  3. }

(2)將匹配URI爲some/path的請求拋給http://127.0.0.1

 
  1. location /some/path/ {
  2. proxy_pass http://127.0.0.1;
  3. }

(3)將匹配URI爲name的請求應用指定的rewrite規則,而後拋給http://127.0.0.1

 
  1. location /name/ {
  2. rewrite /name/( [^/]+ ) /username=$1 break;
  3. proxy_pass http://127.0.0.1;
  4. }
 

http proxy模塊參數詳解

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

image_1crrhm9b11fmi1oe2gerr1mlah4n.png-368kB

 

反向代理多虛擬主機節點服務器測試

從測試結果能夠看出,已經實現了反向代理,負載均衡功能,可是有一個特殊問題,出來的結果並非帶有sl的字符串,而是bbs的字符串,根據訪問結果,咱們推測是訪問了Web節點下bbs的虛擬主機,明明代理的是sl虛擬主機,爲何結果是訪問了後端的bbs虛擬主機

image_1crrnbfkn530581163m4n8g9.png-19.9kB

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

proxy_set_header host $host;

 
  1. worker_processes 1;
  2. events {
  3. worker_connections 1024;
  4. }
  5. http {
  6. include mime.types;
  7. default_type application/octet-stream;
  8. sendfile on;
  9. keepalive_timeout 65;
  10. upstream www_server {
  11. server 192.168.200.68:80 weight=1;
  12. server 192.168.200.69:80 weight=1;
  13. }
  14. server {
  15. listen 80;
  16. server_name sl.yunjisuan.com;
  17. location / {
  18. proxy_pass http://www_server;
  19. proxy_set_header host $host;
  20. }
  21. }
  22. }

image_1crrnom2k1c6t1kp9q5krrf17ne16.png-26.6kB

 

反向代理後的節點服務器記錄用戶IP測試

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

image_1crro073pbiq1j6opvtmru9pd1j.png-31.5kB

解決辦法一樣是在反向代理服務器增長以下一行參數:

proxy_set_header X-Forwarded-For $remote_addr;

這是反向代理時,節點服務器獲取用戶真實IP的必要功能配置

在反向代理請求後端節點服務器的請求頭中增長獲取的客戶端IP的字段信息,而後節點後端能夠經過程序或者相關的配置接收X-Forwarded-For傳過來的用戶真實IP的信息。

 
  1. worker_processes 1;
  2. events {
  3. worker_connections 1024;
  4. }
  5. http {
  6. include mime.types;
  7. default_type application/octet-stream;
  8. sendfile on;
  9. keepalive_timeout 65;
  10. upstream www_server {
  11. server 192.168.200.68:80 weight=1;
  12. server 192.168.200.69:80 weight=1;
  13. }
  14. server {
  15. listen 80;
  16. server_name sl.yunjisuan.com;
  17. location / {
  18. proxy_pass http://www_server;
  19. proxy_set_header host $host;
  20. proxy_set_header X-Forwarded-For $remote_addr;
  21. }
  22. }
  23. }

image_1crrp7d581kob2m3auqtl1kdc40.png-24.5kB

特別注意,雖然反向代理已經配好了,可是節點服務器(WEBA和B)須要的訪問日誌若是要記錄用戶的真實IP,還必須進行日誌格式配置,這樣才能把代理傳過來的X-Forwarded-For頭信息記錄下來,具體配置爲

WEBA和WEBA配置文件是同樣的只是IP不一樣

 
  1. worker_processes 1;
  2. events {
  3. worker_connections 1024;
  4. }
  5. http {
  6. include mime.types;
  7. default_type application/octet-stream;
  8. sendfile on;
  9. keepalive_timeout 65;
  10. server_tokens off;
  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.yunjisuan.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 sl.yunjisuan.com;
  26. location / {
  27. root html/sl;
  28. index index.html index.htm;
  29. }
  30. access_log logs/access_sl.log main;
  31. }
  32. }
  33. 配置文件詳解
  34. log_format --->記錄字段順序
  35. $remote_addr --->來源IP
  36. $remote_user --->來源用戶
  37. [$time_local] --->來源時間
  38. $request --->請求
  39. $status --->狀態碼
  40. $body_bytes_sent --->主體,發送的大小
  41. $http_referer --->來源的瀏覽器
  42. $http_user_agent --->用戶的客戶端
  43. $http_x_forwarded_for --->這是反向代理時,節點服務器獲取用戶真實IP的必要功能配置
  44. 若是但願在第一行顯示,能夠替換掉第一行的$remote_addr變量

image_1crrq5nj9iph1ue21e3o17lj170n4d.png-25.5kB

 

清空NginxWEBA和B日誌文件並在瀏覽器輸入域名測試

 
  1. cd /usr/local/nginx/logs
  2. > access_bbs.log
  3. > access_sl.log
  4. 沒在WINDOWS作映射的話先去作一下
  5. 由於虛擬機是NAT模式,因此真實IP是網關IP

image_1crrrjrcptlm1nr2bphc7h1uk9ig.png-11.1kB

image_1crrqfg1rr4s10r2193b30v1n4d4q.png-63.3kB

 

反向代理相關重要基礎參數的總結

image_1crrqlv1gqk5mbsu4m1r8h1qn757.png-202.4kB

 

配置文件用include方式包含到虛擬主機配置裏

cd /usr/local/nginx/conf

touch proxy.conf

把下面的重要參數放到proxy.conf在反向代理配置文件用include方式調用

 
  1. proxy_set_header host $host;
  2. proxy_set_header x-forwarded-for $remote_addr;
  3. proxy_connect_timeout 60;
  4. proxy_send_timeout 60;
  5. proxy_read_timeout 60;
  6. proxy_buffer_size 4k;
  7. proxy_buffers 4 32k;
  8. proxy_busy_buffers_size 64k;
  9. proxy_temp_file_write_size 64k;
 
  1. worker_processes 1;
  2. events {
  3. worker_connections 1024;
  4. }
  5. http {
  6. include mime.types;
  7. default_type application/octet-stream;
  8. sendfile on;
  9. keepalive_timeout 65;
  10. upstream www_server {
  11. server 192.168.200.68:80 weight=1;
  12. server 192.168.200.69:80 weight=1;
  13. }
  14. server {
  15. listen 80;
  16. server_name sl.yunjisuan.com;
  17. location / {
  18. proxy_pass http://www_server;
  19. include proxy.conf;
  20. }
  21. }
  22. }

image_1crrr9ve81cpc4lt1r401qkl1iol5k.png-49kB

 

include方式在windows瀏覽器測試

image_1crrrhevo1r1sokc9sj155krl9e5.png-13kB

image_1crrrgchr16g01dem5m0u461ei4b5.png-61.2kB

 

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

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

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

image_1crrrvrm0ilb1v2mivbr6k1jvqk9.png-197.1kB

 

根據URL方式測試反向代理服務器配置文件以下

WEBA請求sl.yunjisuan.com/static/xx地址時,實現由靜態服務器池處理請求。(192.168.200.68)

WEBB請求sl.yunjisuan.com/upload/xx地址時,實現由upload上傳服務器池處理請求。(192.168.200.69)

WEBC其餘訪問請求,全都由默認的動態服務器池處理請求。(192.168.200.75)

include方式調用的文件

 

以location方案實現

 
  1. worker_processes 1;
  2. events {
  3. worker_connections 1024;
  4. }
  5. http {
  6. include mime.types;
  7. default_type application/octet-stream;
  8. sendfile on;
  9. keepalive_timeout 65;
  10. upstream default {
  11. server 192.168.200.75:80 weight=1;
  12. }
  13. upstream static {
  14. server 192.168.200.68:80 weight=1;
  15. }
  16. upstream upload {
  17. server 192.168.200.69:80 weight=1;
  18. }
  19. server {
  20. listen 80;
  21. server_name sl.yunjisuan.com;
  22. location / {
  23. proxy_pass http://default;
  24. include proxy.conf;
  25. }
  26. location /static/ {
  27. proxy_pass http://static;
  28. include proxy.conf;
  29. }
  30. location /upload/ {
  31. proxy_pass http://upload;
  32. include proxy.conf;
  33. }
  34. }
  35. }
 

以if語句實現

 
  1. worker_processes 1;
  2. events {
  3. worker_connections 1024;
  4. }
  5. http {
  6. include mime.types;
  7. default_type application/octet-stream;
  8. sendfile on;
  9. keepalive_timeout 65;
  10. upstream default {
  11. server 192.168.200.75:80 weight=1;
  12. }
  13. upstream static {
  14. server 192.168.200.68:80 weight=1;
  15. }
  16. upstream upload {
  17. server 192.168.200.69:80 weight=1;
  18. }
  19. server {
  20. listen 80;
  21. server_name sl.yunjisuan.com;
  22. location / {
  23. proxy_pass http://default;
  24. include proxy.conf;
  25. if ($request_uri ~* "^/static/(.*)$"){
  26. proxy_pass http://static/$1;
  27. }
  28. if ($request_uri ~* "^/upload/(.*)$"){
  29. proxy_pass http://upload/$1;
  30. }
  31. }
  32. }
  33. }

image_1crrvudmd1cqo9v41stst1e2a01g.png-50.9kB

 

WEBA靜態測試結果(curl方式)

cd /usr/local/nginx/html

cd sl

mkdir static

echo "static" > static/index.html

curl http://sl.yunjisuan.com/static/

image_1crs07hf3s9n2mo1lvl4lf74s1t.png-39.3kB

 

WEBB上傳測試結果(curl方式)

cd /usr/local/nginx/html

cd sl

mkdir upload

echo "upload" > upload/index.html

curl http://sl.yunjisuan.com/upload/

image_1crs0gcdf11dg1r9qdh112bhiev2a.png-40.2kB

 

WEBC默認測試結果(curl方式)

cd /usr/local/nginx/html

echo "default" > default/index.html

curl http://sl.yunjisuan.com

image_1crs16hjl1n83ktp1j2b19tfpek34.png-35.2kB

 

windows全部網頁測試結果

http://sl.yunjisuan.com

http://sl.yunjisuan.com/static/index.html

http://sl.yunjisuan.com/upload/index.html


image_1crs1d37812ngvpu3abmpr17rg4b.png-11kB


image_1crs1djt81aggvqmqdtg1u1atq4o.png-14.1kB


image_1crs1eam71t7i1ombvoa1lou32555.png-13.4kB

相關文章
相關標籤/搜索