Nginx 負載均衡反向代理

一、集羣介紹以及常用集羣硬件知識介紹及選型

1、負載均衡以及高可用集羣的作用
1)、負載均衡集羣的作用:
a、分擔用戶訪問請求及數據流量(負載均衡)
b、保持業務連續性,即 7x24 小時服務(高可用性)
c、應用於 web 業務及數據庫從庫等服務器的業務。
負載均衡集羣典型的開源軟件:LVS、Nginx、Haproxy
2)、高可用集羣的作用:
a、當一臺機器宕機時,另外一臺機器接管宕機的機器的 IP 資源和服務資源,提供服務。
b、常用於不易實現負載均衡的應用,比如負載均衡器,主數據庫、主存儲對之間。
高可用集羣常用的開源軟件:Keepalived、Heartbeat(架構師班講)
2、對於集羣軟硬件產品如何選型
a、當企業業務重要,技術力量又薄弱,並且希望出錢購買產品及獲取剛好的服務時,可以選擇硬件負載均衡產品,如 F5、Netscaler、Radware 等,此類公司多爲傳統的大型非互聯網企業,如銀行、證券、金融、寶馬、奔馳等。(硬件負載均衡服務器價格幾十萬,好的上百萬)
b、對於門戶網站來說,大多會並用軟件及硬件產品來分擔單一產品的風險,如淘寶、騰訊、新浪等。融資了的企業會購買企業硬件產品,如趕集等網站。
c、中小型互聯網企業,由於起步階段無利潤可賺或利潤很低,會希望通過使用開源免費的方案來解決問題,因此會僱傭專門的運維人員進行維護。例如,51CTO 等。
相比較而言,商業的負載均衡產品成本高,性能好,更穩定,缺點是不能二次開發,開源的負載均衡軟件對運維人員的能力要求較高,如果運維及開發能力強,那麼開源軟件的負載均衡是不錯的選擇,目前的互聯網行業更偏向使用開源的負載均衡軟件。
Nginx 負載均衡反向代理
Netscaler 負載均衡產品
Nginx 負載均衡反向代理
F5 負載均衡產品

二、Nginx 負載均衡

正向代理:代理代替局域網內的用戶去訪問外部站點資源
反向代理:代理代替用戶去訪問後面的 web 節點或者應用服務器
1、實現 nginx 負載均衡的組件模塊有兩個,見下表:
Nginx 負載均衡反向代理
2、負載均衡實驗環境準備:
Nginx 負載均衡反向代理
3、安裝 Nginx 並測試:(Nginx 安裝過程略)
1)、配置首頁文件:

[root@lamp01 ~]# cat /var/html/www/index.html 
www.etiantian.org 133
[root@lnmp02 ~]# cat /application/nginx/html/www/index.html 
www.etiantian.org 135

2)、在 lb01 負載均衡器上 curl 兩個 web 服務器的 IP 結果:

[root@lb01 ~]# curl 192.168.153.133
www.etiantian.org 133
[root@lb01 ~]# curl 192.168.153.135
www.etiantian.org 135

3)、編輯 lb01 負載均衡器 nginx 的配置文件如下:

[root@lb01 ~]# vim /application/nginx/conf/nginx.conf
worker_processes  1;
events {
        worker_connections  1024;
}
http {
        include       mime.types;
        default_type  application/octet-stream;
        sendfile        on;
        keepalive_timeout  65;
   upstream www_server_pools{    #  定義的服務器節點。
   # ip_hash;
   server 192.168.136.150:80  weight=1;
   server 192.168.136.151:80  weight=1;
}
server {      #  定義一個代理的負載均衡域名虛擬主機。
        listen       80;
        server_name  www.etiantian.org;
        location / {
                proxy_pass http://www_server_pools;   
#  訪問 www.etiantian.org ,請求發送給 www_server_pools 裏面定義的節點。
        }
   }    
}

4)、配置好檢查語法並平滑加載配置:

[root@lb01 ~]# /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@lb01 ~]# /application/nginx/sbin/nginx -s reload

5)、在本地做 hosts 解析:

[root@lb01 ~]# vi /etc/hosts
192.168.153.141 www.etiantian.org

6)、測試負載均衡實現的效果:

[root@lb01 ~]# for n in `seq 10`;do curl www.etiantian.org;done
www.etiantian.org 135
www.etiantian.org 155
www.etiantian.org 135
www.etiantian.org 155
www.etiantian.org 135
www.etiantian.org 155
www.etiantian.org 135
www.etiantian.org 155
www.etiantian.org 135
www.etiantian.org 155

至此,已經實現了 Nginx 的負載均衡。
4、有關 Nginx 模塊的詳細說明:
詳見官方文檔:http://nginx.org/en/docs/http/ngx_http_upstream_module.html
1)、上面涉及到的 upstream 模塊示例:

Example Configuration
upstream backend {    #  定義的服務器池名字。
server backend1.example.com  weight=5;    #  沒有加端口,表示默認 80 端口,權重爲 5 。    
server backend2.example.com:8080;    #  沒有加權重,默認權重爲 1 。    
server unix:/tmp/backend3;    server backup1.example.com:8080   backup;    #  熱備節點,Web 掛點由它接替。     
server backup2.example.com:8080   backup;    #  熱備節點,Web 掛點由它接替。
  提示:端口前面可以是 IP 也可以是域名,通過 DNS 做負載均衡,甚至可以是 VIP 向後轉發。
} server {    location / {        proxy_pass http://backend;   #  用戶訪問到此,轉發到定義好的 backend 服務器池,進而訪問真實的 Web 服務器。  
} }

2)、upstream 模塊內部 server 標籤參數說明:
Nginx 負載均衡反向代理
3)、權重,將 web01 的權重改爲5,測試如下:

[root@lb01 ~]# /application/nginx/sbin/nginx -s reload      
[root@lb01 ~]# for n in `seq 10`;do curl www.etiantian.org;done        
www.etiantian.org 155
www.etiantian.org 155
www.etiantian.org 155
www.etiantian.org 135
www.etiantian.org 155
www.etiantian.org 155
www.etiantian.org 155
www.etiantian.org 155
www.etiantian.org 155
www.etiantian.org 135

4)、熱備配置 web 的高可用(backup 參數):
編輯配置文件把 web02 設爲熱備服務器:
server 192.168.153.155:80 weight=1;
server 192.168.153.135:80 weight=1 backup;
測試如下:

[root@lb01 ~]# for n in `seq 10`;do curl www.etiantian.org;done
www.etiantian.org 155
www.etiantian.org 155
www.etiantian.org 155
www.etiantian.org 155
www.etiantian.org 155
www.etiantian.org 155
www.etiantian.org 155
www.etiantian.org 155
www.etiantian.org 155
www.etiantian.org 155

關掉 web01 服務器上的 nginx 服務測試:

[root@lb01 ~]# for n in `seq 10`;do curl www.etiantian.org;done
www.etiantian.org 135
www.etiantian.org 135
www.etiantian.org 135
www.etiantian.org 135
www.etiantian.org 135
www.etiantian.org 135
www.etiantian.org 135
www.etiantian.org 135
www.etiantian.org 135
www.etiantian.org 135

5、upstream 調度算法:
調度算法一般分爲兩類:
第一類爲靜態調度算法,即負載均衡器根據自身設定的規則進行分配,不需要考慮後端節點服務器的情況;
第二類爲動態調度算法,即負載均衡器會根據後端節點的當前狀態來決定是否分發請求,例如:連接數少的優先獲得請求,響應時間短的優先獲得請求。
1)、靜態調度算法:
① rr 輪詢(默認調度算法,靜態調度算法);
② wrr 權重輪詢(解決新舊服務器性能不均帶來的請求分配問題);
③ ip_hash (會話保持,但會導致負載不均衡)。
2)、動態調度算法:
① fair 算法:
此算法會根據後端節點服務器的響應時間來分配請求,響應時間短的優先分配,這是更加智能的調度算法,此算法可以依據頁面大下和加載時間長短智能地進行負載均衡。Nginx 本身是不支持 fair 調度算法的,若需要這種調度算法,需要下載 Nginx 的相關模塊。
② least_conn 算法:
此算法會根據後端節點的連接數來決定分配情況,哪個機器連接數少就分發。
③ url_hash 算法:
和 Ip_hash 類似,這裏是根據訪問 URL 的 hash 結果來分配請求的,讓每個 URL 定向到同一個後端服務器,後端服務器爲緩存服務器時效果顯著。在 upstream 中加入 hash 語句,server 語句中不能寫入 weight 等其他參數,hash_method 使用的是 hash 算法。
url_hash 按訪問 URL 的 hash 結果來分配請求,使每個 URL 定向到同一個後端服務器,可以進一步提高後端緩存服務器的效率命中率。Nginx 本身是不支持該算法的,若需要使用這個算法,需要安裝 Nginx 的 hash 模塊軟件包。
④ 一致性 HASH 算法:
一致性 HASH 算法一般用於代理後端業務爲緩存服務(squid、memcached)的場景,通過將用戶請求的 URI 或者指定字符串進行計算,然後調度到後端的服務器上,此後用戶查找同一個 URI 或者指定字符串都會被調度到這一臺服務器上,因此後端的每個節點緩存的內容都是不同的,一致性 HASH 算法可以解決後端某個或幾個節點宕機後,緩存的數據動盪最小,該算法比較複雜。
6、Http_proxy_module 模塊
1)、Proxy_pass 指令介紹:
Proxy_pass 指令屬於 ngx_http_proxy_module 模塊,此模塊可以將請求轉發到另一臺服務器,在實際的反向代理工作中,會通過 location 功能匹配指定的 URL,然後把接收到的符合匹配 URI 的請求通過 proxy_pass 拋給定義好的 upstream 節點池。
2)、Http_proxy 模塊相關參數:
Nginx 負載均衡反向代理
7、經過反向代理後的節點服務器記錄真實 IP 企業案例:
準備工作:打開一臺服務器模擬負載均衡的客戶端,做 hosts 解析並訪問負載均衡服務器。

[root@lb01 ~]# vi /etc/hosts
192.168.153.141 www.etiantian.org bbs.etiantian.org
[root@lb01 ~]# for n in `seq 10`;do curl www.etiantian.org;done       # 輪詢兩個 web 服務器
www.etiantian.org 155
www.etiantian.org 135
www.etiantian.org 155
www.etiantian.org 135
www.etiantian.org 155
www.etiantian.org 135
www.etiantian.org 155
www.etiantian.org 135
www.etiantian.org 155
www.etiantian.org 135

① 開啓 web 服務器記錄訪問日誌功能:

server {
        listen       80;
        server_name  www.etiantian.org;
        location / {
            root   html/www;
            index  index.html index.htm;
     }
            access_log logs/access_www.log main;
}

② 在負載均衡服務器添加如下配置:

[root@lb01 ~]# vim  /application/nginx/conf/nginx.conf
worker_processes  1;
events {
        worker_connections  1024;
}
http {
        include       mime.types;
        default_type  application/octet-stream;
        sendfile        on;
        keepalive_timeout  65;
   upstream www_server_pools{
   # ip_hash;
   server 192.168.153.135:80  weight=1;
   server 192.168.153.155:80  weight=1;
}
server {
        listen       80;
        server_name  www.etiantian.org;
        location / {
          proxy_pass http://www_server_pools;
          proxy_set_header Host    $host;
          proxy_set_header X-Forwarded-For $remote_addr;
          }
        }
        #include extra/lb_www.conf;
        #include extra/lb_bbs.conf;
    # $remote_addr 這是客戶端的 IP 地址,將客戶端的地址傳給 X-Forwarded-For ,實現在訪問日誌中記錄客戶端用戶的真實 IP 。

③ Nginx 反向代理重要參數說明
Nginx 負載均衡反向代理
④ Http proxy 模塊相關參數的配置:

[root@lb01 conf]# vim proxy.conf
  1 proxy_set_header Host $host;
  2 proxy_set_header X-Forward-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;
[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 www_server_pools{
   # ip_hash;
   server 192.168.153.155:80  weight=1;
   server 192.168.153.135:80  weight=1;
}
server {
        listen       80; 
        server_name  www.etiantian.org;
        location / {
          proxy_pass http://www_server_pools;
          include proxy.conf;     #  把上面配置參數的文件通過 include 功能包含到主配置文件裏。
         }
        }    
        #include extra/lb_www.conf;
        #include extra/lb_bbs.conf;
        #include extra/lb_blog.conf;
}
[root@lb01 conf]# ../sbin/nginx -t
[root@lb01 conf]# ../sbin/nginx -s reload 
問題:檢查語法沒有問題,但修改成爲以上的 include 後訪問日誌看不到用戶真實 IP 了。

8、根據 URL 中的目錄地址實現代理轉發
1)、案例背景:
通過 Nginx 實現動靜分離,即通過 Nginx 反向代理配置規則實現讓動態資源和靜態資源及其他業務分別由不同的服務器解析,以解決網站性能、安全、用戶體驗等重要問題。
Nginx 負載均衡反向代理
上圖爲企業常見的動靜分離集羣架構圖,此架構圖適合網站前端只使用同一個域名提供服務的場景,例如用戶訪問的域名是 www.etiantian.org,然後當用戶請求 www.etiantian.org/upload/xx 地址的時候,代理會分配請求到上傳服務器池處理數據;當用戶請求www.etiantian.org/static/xx 地址的時候,代理會分配請求到靜態服務器池請求數據;當用戶請求 www.etiantian.org/xx 地址的時候,即不包含上述指定的目錄地址路徑的時候,代理會分配請求到默認的動態服務器池請求數據(提示:上述 xx 可以表示任何路徑)。
2)、案例配置模擬場景準備:
Nginx 負載均衡反向代理
① 靜態數據服務器環境準備: LNMP01

[root@lnmp01 ~]# cd /application/nginx/html/www/
[root@lnmp01 www]# mkdir static                     # 創建站點目錄(模擬靜態數據目錄)
[root@lnmp01 www]# cd static/
[root@lnmp01 static]# vim index.html               # 編輯首頁文件 
static content 
[root@lnmp01 static]# vim /etc/hosts
192.168.153.155 www.etiantian.org
[root@lnmp01 static]# curl www.etiantian.org/static/index.html        # hosts 解析本地測試成功
static content

② 上傳數據服務器環境準備: LNMP02

[root@lnmp02 ~]# cd /application/nginx/html/www/
[root@lnmp02 www]# mkdir upload
[root@lnmp02 www]# cd upload/
[root@lnmp02 upload]# vim index.html
upload content
[root@lnmp01 static]# vim /etc/hosts
192.168.153.135 www.etiantian.org
[root@lnmp02 upload]# curl www.etiantian.org/upload/index.html
upload content

③ 默認的動態服務器環境準備: LNMP03

[root@lnmp03 ~]# cd /application/nginx/html/www/
[root@lnmp03 www]# mkdir default
[root@lnmp03 www]# cd default/
[root@lnmp03 default]# vim index.html
default content
[root@lnmp01 static]# vim /etc/hosts
192.168.153.156 www.etiantian.org
[root@lnmp03 default]# curl www.etiantian.org/default/index.html
default content

3)、案例配置實戰:
方案一:以 location 方案實戰:

[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 www_server_pools{
# ip_hash;
#       server 192.168.153.155:80  weight=1;
#       server 192.168.153.135:80  weight=1;
#}
upstream default_pools {
        server 192.168.153.156:80 weight=1;
}
upstream static_pools { 
        server 192.168.153.155:80 weight=1;
}
upstream upload_pools {  
        server 192.168.153.135:80 weight=1;
}
        server {
                listen       80;
                server_name  www.etiantian.org;
#               location / {
#                       proxy_pass http://www_server_pools;
#                       include proxy.conf;
#                }
                location / {
                        proxy_pass http://default_pools;    #  將所有不符合 static 和 upload 的請求全部交給 default_pools 處理。     
                        include proxy.conf;
                 }
                location /static/ {
                        proxy_pass http://static_pools; # 將符合 static 的請求交給 static_pools 處理。
                        include proxy.conf;
                 }
                location /upload/ {
                        proxy_pass http://upload_pools; # 將符合 upload 的請求交給 upload_pools 處理。
                        include proxy.conf;
                 }    
        }
}

通過 Windows 瀏覽器訪問測試配置結果:
① 訪問靜態數據服務器的請求:
Nginx 負載均衡反向代理
② 訪問上傳服務器的請求:
Nginx 負載均衡反向代理
③ 訪問默認的動態請求:
Nginx 負載均衡反向代理
④ 在默認的動態請求上傳圖片測試:
Nginx 負載均衡反向代理
方案二:以 if 語句實現:【略略略】
Nginx 負載均衡反向代理
4)、根據 URL 目錄地址轉發的應用場景:
·· 根據 http 的 URL 進行轉發的應用情況,被稱爲第 7 層(應用層)的負載均衡,而 LVS 的負載均衡一般用於 TCP 等的轉發,因此被稱爲第 4 層(傳輸層)的負載均衡。
在企業中,有時希望只用一個域名對外提供服務,不希望使用多個域名對應同一個產品業務,此時就需要在代理服務器上通過配置規則,使得匹配不同規則的請求會交給不同的服務器池處理。
① 業務的域名沒有拆分或者不希望拆分,但希望實現動靜分離、多業務分離;
② 不同的客戶端設備(例如手機和 PC 端)使用同一個域名訪問同一個業務網站,就需要根據規則將不同設備的用戶請求交給後端不同的服務器處理,以便得到最佳的用戶體驗。
9、通過識別 user_agent 分發請求案例:
此案例發生的背景:
Nginx 負載均衡反向代理
解決此方案的架構邏輯圖:
Nginx 負載均衡反向代理
實踐操作:根據客戶端設備(user_agent)轉發請求實戰:
實現的思路:
① 如果請求的瀏覽器爲 IE 瀏覽器(MSIE),則讓請求由 static_pools 池處理;
② 如果請求的瀏覽器爲谷歌瀏覽器(Chrome),則讓請求由 upload_pools 處理。
③ 如果請求的瀏覽器爲其他的,則拋給 default_pools 處理
1)、據電腦客戶端瀏覽器的不同設置對應的匹配規則:

location / {
    if ($http_user_agent ~* "MSIE")
       {
          proxy_pass http://static_pools;
       }
    if ($http_user_agent ~* "Chrome")
        {
          proxy_pass http://upload_pools;
        }
}

2)、配置過程及結果如下:

[root@lb01 conf]# cp nginx.conf nginx.conf.yu.20180727
[root@lb01 conf]# vim nginx.conf
[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 default_pools {
             server 192.168.153.156:80 weight=1;
           }
        upstream static_pools {
             server 192.168.153.155:80 weight=1;
           }
        upstream upload_pools {
             server 192.168.153.135:80 weight=1;
           }    
        server {
          listen       80;
          server_name  www.etiantian.org;
          location / {
          if ($http_user_agent ~* "MSIE")
              {
               proxy_pass http://static_pools;
              }
          if ($http_user_agent ~* "Chrome")
              {
               proxy_pass http://upload_pools;
              }
               proxy_pass http://default_pools;
               include proxy.conf;
            }
         }
  } 

3)、以上配置可以實現的效果:
① 訪問 static 出現 404 錯誤(靜態 static 服務器只有 MSIE 瀏覽器才能訪問到):
Nginx 負載均衡反向代理
② 訪問 upload 代理可以轉發請求到上傳服務器匹配成功):
Nginx 負載均衡反向代理
Nginx 負載均衡反向代理
4)、此時可通過查看訪問日誌看到用戶是從哪個瀏覽器訪問到服務器的:
① 在 156 默認的動態瀏覽器查看訪問日誌:(默認,都可以匹配)

192.168.136.161 - - [23/May/2018:17:59:44 +0800] "GET /default/ HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.90 Safari/537.36 2345Explorer/9.3.2.17331"
192.168.136.161 - - [23/May/2018:18:00:03 +0800] "GET /images/oldgirl.jpg HTTP/1.0" 200 98431 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.90 Safari/537.36 2345Explorer/9.3.2.17331"

② 在 135 上傳瀏覽器查看訪問日誌:(上傳匹配谷歌瀏覽器)

192.168.136.161 - - [22/Jun/2018:21:52:43 +0800] "GET /static/ HTTP/1.0" 404 570 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.90 Safari/537.36 2345Explorer/9.3.2.17331"
192.168.136.161 - - [22/Jun/2018:21:54:32 +0800] "GET /upload/ HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.90 Safari/537.36 2345Explorer/9.3.2.17331"

③ 在 155 靜態服務器查看訪問日誌:(因爲本人不是 MSIE 瀏覽器)
192.168.136.161 - - [22/Jun/2018:16:10:41 +0800] "GET / HTTP/1.0" 200 22 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
5)、其他案例:還可以通過判斷用戶的手機來代理轉發不同的服務器:
配置如下(過程略):

location / {
    if ($http_user_agent ~* "android")
       {
          proxy_pass http://static_pools;
       }
    if ($http_user_agent ~* "iphone")
        {
          proxy_pass http://upload_pools;
        }
}
  提示:以上配置可以實現代理將客戶端不同手機系統的請求轉發給適合用戶的不同的瀏覽器。

10、根據擴展名轉發的應用場景:
可根據擴展名實現資源動靜分離訪問,例如:圖片、視頻等請求靜態服務器池,PHP、JSP 請求動態服務器池,示例代碼如下:(略)
Nginx 負載均衡反向代理
11、Nginx 負載均衡檢測節點狀態:
利用第三方 Nginx 插件監控代理後端節點的服務器:
淘寶技術團隊開發了一個 Tengine(Nginx 的分支)模塊 nginx_upstream_check_module,用於提供主動式後端服務器健康檢查,通過它可以檢測後端 realserver 的健康狀態,如果後端 RS 不可用,則所有的請求就不會轉發到該節點上。
Tengine 原生支持這個模塊,但是 Nginx 需要通過打補丁的方式將該模塊添加到 Nginx 中,補丁下載地址:(https://github.com/yaoweibin/nginx_upstream_check_module

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章