Nginx正反向代理、負載均衡等功能實現配置

系統環境:

VirtualBox Manager

Centos6.4

nginx1.10.0

IP對應的機器名:

      IP                機器名               角色名

10.0.0.139      [elk]                     client

10.0.0.136      [lvs-master]        nginx server

10.0.0.137      [kvm]                   web server 1

10.0.0.111      [lvs-backup]        web server 2

一、正向代理

概念這裏不在介紹,可以參考此文http://my.oschina.NET/yoyoko/blog/147414。


1.1 環境介紹


1.2 配置介紹

Nginx server:(內網地址:10.0.0.136,外網地址:172.16.27.64)

使用VirtualBox Manager虛擬出雙網卡。

[plain] view plain copy
  1. [root@lvs-master conf.d]# ifconfig  
  2. eth0      Link encap:Ethernet  HWaddr 08:00:27:30:56:99  
  3.           inet addr:10.0.0.136  Bcast:10.255.255.255  Mask:255.0.0.0  
  4.           inet6 addr: fe80::a00:27ff:fe30:5699/64 Scope:Link  
  5.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
  6.           RX packets:891978 errors:0 dropped:0 overruns:0 frame:0  
  7.           TX packets:9509 errors:0 dropped:0 overruns:0 carrier:0  
  8.           collisions:0 txqueuelen:1000  
  9.           RX bytes:81841095 (78.0 MiB)  TX bytes:13339058 (12.7 MiB)  
  10.   
  11. eth1      Link encap:Ethernet  HWaddr 08:00:27:55:4C:72  
  12.           inet addr:172.16.27.64  Bcast:172.16.27.255  Mask:255.255.255.0  
  13.           inet6 addr: fe80::a00:27ff:fe55:4c72/64 Scope:Link  
  14.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
  15.           RX packets:913671 errors:0 dropped:0 overruns:0 frame:0  
  16.           TX packets:22712 errors:0 dropped:0 overruns:0 carrier:0  
  17.           collisions:0 txqueuelen:1000  
  18.           RX bytes:109369858 (104.3 MiB)  TX bytes:1903855 (1.8 MiB)  
  19.   
  20. lo        Link encap:Local Loopback  
  21.           inet addr:127.0.0.1  Mask:255.0.0.0  
  22.           inet6 addr: ::1/128 Scope:Host  
  23.           UP LOOPBACK RUNNING  MTU:16436  Metric:1  
  24.           RX packets:36222 errors:0 dropped:0 overruns:0 frame:0  
  25.           TX packets:36222 errors:0 dropped:0 overruns:0 carrier:0  
  26.           collisions:0 txqueuelen:0  
  27.           RX bytes:3899937 (3.7 MiB)  TX bytes:3899937 (3.7 MiB)  


[plain] view plain copy
  1. [root@lvs-master conf.d]# cat zxproxy.conf  
  2. server {  
  3.     listen       80;   #監聽的端口  
  4.     server_name  10.0.0.136;  #server的內容地址,與client需要網絡互通  
  5.   
  6.   
  7.     resolver 172.16.5.1;   #DNS,這個是DNS,訪問外網  
  8.     location / {  
  9.            proxy_pass http://$http_host$request_uri;   #$http_host和$request_uri是nginx系統變量,不需要替換,保持原樣  
  10.                 }  


Nginx client:

只有一個內網網卡,通過訪問Nginx server去訪問internet,其實翻牆、肉雞、之類的俗稱就是這個原理。

[plain] view plain copy
  1. [root@kvm ~]# ifconfig  
  2. eth0      Link encap:Ethernet  HWaddr 08:00:27:72:8C:3B  
  3.           inet addr:10.0.0.137  Bcast:10.255.255.255  Mask:255.0.0.0  
  4.           inet6 addr: fe80::a00:27ff:fe72:8c3b/64 Scope:Link  
  5.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
  6.           RX packets:1462448 errors:0 dropped:0 overruns:0 frame:0  
  7.           TX packets:21130 errors:0 dropped:0 overruns:0 carrier:0  
  8.           collisions:0 txqueuelen:1000  
  9.           RX bytes:145119904 (138.3 MiB)  TX bytes:2814635 (2.6 MiB)  
  10.   
  11. lo        Link encap:Local Loopback  
  12.           inet addr:127.0.0.1  Mask:255.0.0.0  
  13.           inet6 addr: ::1/128 Scope:Host  
  14.           UP LOOPBACK RUNNING  MTU:16436  Metric:1  
  15.           RX packets:60800 errors:0 dropped:0 overruns:0 frame:0  
  16.           TX packets:60800 errors:0 dropped:0 overruns:0 carrier:0  
  17.           collisions:0 txqueuelen:0  
  18.           RX bytes:4831102 (4.6 MiB)  TX bytes:4831102 (4.6 MiB)  
  19.   
  20. [root@kvm ~]# wget www.baidu.com  
  21. --2016-06-08 13:02:08--  http://www.baidu.com/  
  22. 正在解析主機 www.baidu.com... 失敗:域名解析暫時失敗。     #無法訪問百度  
  23. wget: 無法解析主機地址 “www.baidu.com”  
  24.   
  25. [root@kvm ~]# export http_proxy=http://10.0.0.136:80 #設定環境變量,指定代理服務器的ip及端口  
  26.   
  27. [root@kvm ~]# wget www.baidu.com      #可以成功訪問百度了  
  28. --2016-06-08 13:08:15--  http://www.baidu.com/  
  29. 正在連接 10.0.0.136:80... 已連接。  
  30. 已發出 Proxy 請求,正在等待迴應... 200 OK  
  31. 長度:未指定 [text/html]  
  32. 正在保存至: “index.html.1”  
  33.   
  34.     [ <=>                                                  ] 99,762      --.-K/s   in 0.07s  
  35.   
  36. 2016-06-08 13:08:16 (1.36 MB/s) - “index.html.1” 已保存 [99762]  


二、反向代理

介紹文章同正向代理

2.1 環境介紹



1.下面來看下測試頁面:

[python] view plain copy
  1. [root@kvm ~]# yum install httpd  
  2. [root@kvm ~]# echo "<html>10.0.0.137</html>" > /var/www/html/index.html  
  3. [root@lvs-backup ~]# yum install httpd  
  4. [root@lvs-backup~]# echo "<html>10.0.0.111</html>" > /var/www/html/index.html  


2.看下效果:

[plain] view plain copy
  1. [root@lvs-backup html]# curl 10.0.0.111  
  2. <html>  
  3. 10.0.0.111  
  4. </html>  
  5. [root@lvs-backup html]# curl 10.0.0.137  
  6. <html>  
  7. 10.0.0.137  
  8. </html>   
  9. ##都成功了,我們進行下一步。  

2.2 配置介紹

[plain] view plain copy
  1. [root@lvs-master conf.d]# ls         #nginx目錄下的配置文件  
  2. zxproxy.conf  
  3. [root@lvs-master conf.d]# cp zxproxy.conf fxproxy.conf  #複製一份,之前是正向代理,現在是反向代理  
  4. [root@lvs-master conf.d]# mv zxproxy.conf zxproxy.conf.bak  

[python] view plain copy
  1. [root@lvs-master conf.d]# cat fxproxy.conf   
  2. server {  
  3.     listen       80;  
  4.     server_name  10.0.0.136#根據環境介紹,nginx server ip  
  5.   
  6.     location / {  
  7.            proxy_pass http://10.0.0.137#被代理的服務器ip  
  8.                 }  
  9.   
  10. #proxy_pass: proxy_pass URL  
  11. #默認值:NO  
  12. #使用字段:location,location中的if字段  
  13. #這個參數設置被代理服務器的地址和被映射的URL,地址可以使主機名、域名、IP加端口的模式,如:  
  14. #proxy_pass    http://192.168.1.6:8099/linuxtone/;  
  15.   
  16. [root@lvs-master conf.d]# service nginx restart #重啓加載配置  

看下結果:

[plain] view plain copy
  1. #先登錄到實驗環境中的clinet機上,ip如下:  
  2. [root@elk ~]# ifconfig                           
  3. eth0      Link encap:Ethernet  HWaddr 08:00:27:3D:40:40  
  4.           inet addr:10.0.0.139  Bcast:10.255.255.255  Mask:255.0.0.0  
  5.           inet6 addr: fe80::a00:27ff:fe3d:4040/64 Scope:Link  
  6.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
  7.           RX packets:2618345 errors:0 dropped:0 overruns:0 frame:0  
  8.           TX packets:247926 errors:0 dropped:0 overruns:0 carrier:0  
  9.           collisions:0 txqueuelen:1000  
  10.           RX bytes:336182790 (320.6 MiB)  TX bytes:35145157 (33.5 MiB)  
  11.   
  12. lo        Link encap:Local Loopback  
  13.           inet addr:127.0.0.1  Mask:255.0.0.0  
  14.           inet6 addr: ::1/128 Scope:Host  
  15.           UP LOOPBACK RUNNING  MTU:16436  Metric:1  
  16.           RX packets:177352 errors:0 dropped:0 overruns:0 frame:0  
  17.           TX packets:177352 errors:0 dropped:0 overruns:0 carrier:0  
  18.           collisions:0 txqueuelen:0  
  19.           RX bytes:26547640 (25.3 MiB)  TX bytes:26547640 (25.3 MiB)  
  20.   
  21. [root@elk ~]# curl 10.0.0.136    #訪問反向代理服務器  
  22. <html>  
  23. 10.0.0.137                   
  24. </html>  
  25. #我們看到訪問代理服務器,結果被轉發到了web server1上。  
  26.   
  27. #接下來我們分別看下nginx-server和web-server1的日誌:  
  28. nginx-server:  
  29. [root@lvs-master ~]# tail /var/log/nginx/access.log  
  30. 10.0.0.139- - [08/Jun/2016:15:35:43 +0800] "GET / HTTP/1.1" 200 26 "-" "curl/7.19.7   
  31. (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2" "-"  
  32.   
  33. web-server:  
  34. [root@kvm httpd]# tail /var/log/httpd/access_log  
  35. 10.0.0.136 - - [08/Jun/2016:15:21:12 +0800] "GET / HTTP/1.0" 200 26 "-" "curl/7.19.7   
  36. (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"  
  37.   
  38. ##我們看到nginx-server上的nginx的日誌,顯示訪問的用戶是10.0.0.139也就是我們環境的clinet,  
  39. #而web-server上顯示的ip是10.0.0.136,也就是nginx-server。  
  40. #說白了反向代理,對客戶來說nginx-server就是真正的服務器,實際上,當用戶訪問nginx-server的時候,會將請求轉發到  
  41. #web-server1上,然後web-server1將請求的結果發給nginx-server,然後由ngin小-server將請求的結果轉交給用戶。  
  42.   
  43. #在web-server上看到的都是代理的ip,能不能也看到真實用戶的ip呢?  
  44.   
  45. [root@lvs-master conf.d]# cat fxproxy.conf                  
  46. server {  
  47.     listen       80;  
  48.     server_name  10.0.0.136;                            #根據環境介紹,nginx server ip  
  49.   
  50.     location / {  
  51.            proxy_pass http://10.0.0.137;                #被代理的服務器ip  
  52.            proxy_set_header  X-Real-IP  $remote_addr;    #多了這行  
  53.                  }  

[plain] view plain copy
  1. [root@lvs-master conf.d]# service nginx restart  
  2. [root@kvm ~]# tail /var/log/httpd/access_log  
  3. 10.0.0.136 - - [08/Jun/2016:16:10:53 +0800] "GET / HTTP/1.0" 200 26 "-" "curl/7.19.7  
  4. (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"  
  5.   
  6. #改了之後還是顯示的是代理服務器的ip,我們去web-server上修改下配置  
  7. [root@kvm ~]# vim /etc/httpd/conf/httpd.conf  
  8. LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined  
  9. LogFormat "%h %l %u %t \"%r\" %>s %b" common  
  10. LogFormat "%{Referer}i -> %U" referer  
  11. LogFormat "%{User-agent}i" agent  
  12.   
  13. #修改爲:(%h指的的訪問的主機,現在改爲訪問的真實主機ip)  
  14. LogFormat "%{X-Real-IP}i</span> %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined  
  15. LogFormat "%h %l %u %t \"%r\" %>s %b" common  
  16. LogFormat "%{Referer}i -> %U" referer  
  17. LogFormat "%{User-agent}i" agent</span>  

[plain] view plain copy
  1. [root@kvm ~]# service httpd restart  
  2. 停止 httpd:                                               [確定]  
  3. 正在啓動 httpd:                                           [確定]  
  4.   
  5. [root@kvm ~]# tail /var/log/httpd/access_log  
  6. 10.0.0.136 - - [08/Jun/2016:16:10:53 +0800] "GET / HTTP/1.0" 200 26 "-" "curl/7.19.7  
  7. (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"  
  8. <span style="color:#FF0000;">10.0.0.139</span> - - [08/Jun/2016:16:16:01 +0800] "GET / HTTP/1.0" 200 26 "-" "curl/7.19.7  
  9. (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"  
  10. #已經變成了真實的訪問地址  


代理多個web服務器:

[plain] view plain copy
  1. [root@lvs-master conf.d]# cat fxproxy.conf  
  2. server {  
  3.     listen       80;  
  4.     server_name  10.0.0.136;  
  5.   
  6.     location / {  
  7.            proxy_pass http://10.0.0.137;  
  8.            proxy_set_header  X-Real-IP  $remote_addr;  
  9.                 }  
  10.     location /web2 {                            #多加個location  
  11.            proxy_pass http://10.0.0.111;  
  12.            proxy_set_header  X-Real-IP  $remote_addr;      
  13.                 }  
  14.   
  15. [root@lvs-backup ~]# cd /var/www/html/   #進入10.0.0.111這個web-server2  
  16. [root@lvs-backup html]# mkdir web  
  17. [root@lvs-backup html]# echo "<html>10.0.0.111</html>" > index.html  
  18. #我們去client上訪問試試:  
  19. [root@elk ~]# curl 10.0.0.136/web2/  
  20. <html>  
  21. 10.0.0.111  
  22. </html>  
  23. #訪問成功  



三、負載均衡

負載均衡實現的方式有很多,常用的lvs四層負載均衡,nginx是七層負載均衡,可以網上查詢相關資料。

3.1 環境介紹

3.2 配置介紹

1.upstream是Nginx的HTTP Upstream模塊,這個模塊通過一個簡單的調度算法來實現客戶端IP到後端服務器的負載均衡。在上面的設定中,通過upstream指令指定了一個負載均衡器的名稱1.2.3.4。這個名稱可以任意指定,在後面需要用到的地方直接調用即可。

2.Nginx的負載均衡模塊目前支持4種調度算法,下面進行分別介紹,其中後兩項屬於第三方調度算法。  

  • 輪詢(默認)。每個請求按時間順序逐一分配到不同的後端服務器,如果後端某臺服務器宕機,故障系統被自動剔除,使用戶訪問不受影響。Weight 指定輪詢權值,Weight值越大,分配到的訪問機率越高,主要用於後端每個服務器性能不均的情況下。

  • ip_hash。每個請求按訪問IP的hash結果分配,這樣來自同一個IP的訪客固定訪問一個後端服務器,有效解決了動態網頁存在的session共享問題。

  • fair。這是比上面兩個更加智能的負載均衡算法。此種算法可以依據頁面大小和加載時間長短智能地進行負載均衡,也就是根據後端服務器的響應時間來分配請求,響應時間短的優先分配。Nginx本身是不支持fair的,如果需要使用這種調度算法,必須下載Nginx的upstream_fair模塊。

  • url_hash。此方法按訪問url的hash結果來分配請求,使每個url定向到同一個後端服務器,可以進一步提高後端緩存服務器的效率。Nginx本身是不支持url_hash的,如果需要使用這種調度算法,必須安裝Nginx 的hash軟件包。

3.upstream 支持的狀態參數

在HTTP Upstream模塊中,可以通過server指令指定後端服務器的IP地址和端口,同時還可以設定每個後端服務器在負載均衡調度中的狀態。常用的狀態有:      

  • down,表示當前的server暫時不參與負載均衡。

  • backup,預留的備份機器。當其他所有的非backup機器出現故障或者忙的時候,纔會請求backup機器,因此這臺機器的壓力最輕。

  • max_fails,允許請求失敗的次數,默認爲1。當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤。

  • fail_timeout,在經歷了max_fails次失敗後,暫停服務的時間。max_fails可以和fail_timeout一起使用。

注,當負載調度算法爲ip_hash時,後端服務器在負載均衡調度中的狀態不能是weight和backup。

我們來看下具體配置:

[python] view plain copy
  1. [root@lvs-master conf.d]# cat ../nginx.conf  
  2. http {  
  3.     include       /etc/nginx/mime.types;  
  4.     default_type  application/octet-stream;  
  5.   
  6.     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '  
  7.                       '$status $body_bytes_sent "$http_referer" '  
  8.                       '"$http_user_agent" "$http_x_forwarded_for"';  
  9.   
  10.     access_log  /var/log/nginx/access.log  main;  
  11.   
  12.     sendfile        on;  
  13.     #tcp_nopush     on;  
  14.   
  15.     keepalive_timeout  65;  
  16.   
  17.     #gzip  on;  
  18. upstream 1.2.3.4 {  
  19.     server 10.0.0.111:80;  
  20.     server 10.0.0.137:80;  
  21.     }  
  22.     include /etc/nginx/conf.d/*.conf;  
  23. }  
  24.   
  25. [root@lvs-master conf.d]# cat slb.confserver   
  26. {   
  27. location / {   
  28.      proxy_pass http://1.2.3.4; proxy_set_header X-Real-IP $remote_addr;   
  29.            }  
  30. #注,upstream是定義在server{ }之外的,不能定義在server{ }內部。定義好upstream之後,用proxy_pass引用一下即可。  



4.測試結果

[python] view plain copy
  1. [root@elk ~]# curl 10.0.0.136  
  2. <html>  
  3. 10.0.0.111  
  4. </html>  
  5. [root@elk ~]# curl 10.0.0.136  
  6. <html>  
  7. 10.0.0.137  
  8. </html>  
  9. [root@elk ~]# curl 10.0.0.136  
  10. <html>  
  11. 10.0.0.111  
  12. </html>  
  13. #結果是server1,2交替出現,說明默認是輪詢方式的負載均衡。  

5.健康檢查

一般健康檢查都需要搞個keepalived,但nginx也有相應的參數可以設置。

  • max_fails,允許請求失敗的次數,默認爲1。當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤。

  • fail_timeout,在經歷了max_fails次失敗後,暫停服務的時間。max_fails可以和fail_timeout一起使用,進行健康狀態檢查。

[python] view plain copy
  1. [root@lvs-master conf.d]# cat ../nginx.conf  
  2. http {     
  3.     include       /etc/nginx/mime.types;  
  4.     default_type  application/octet-stream;  
  5.   
  6.     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '  
  7.                       '$status $body_bytes_sent "$http_referer" '  
  8.                       '"$http_user_agent" "$http_x_forwarded_for"';  
  9.   
  10.     access_log  /var/log/nginx/access.log  main;  
  11.   
  12.     sendfile        on;  
  13.     #tcp_nopush     on;  
  14.   
  15.     keepalive_timeout  65;  
  16.   
  17.     #gzip  on;  
  18.     upstream 1.2.3.4 {  
  19.     server 10.0.0.111:80 weight=1 max_fails=2 fail_timeout=2;  
  20.     server 10.0.0.137:80 weight=1 max_fails=2 fail_timeout=2;  
  21.     }  
  22.     include /etc/nginx/conf.d/*.conf;  
  23.     }  
  24. [root@lvs-master conf.d]# service nginx restart  



6.測試下結果

[python] view plain copy
  1. [root@kvm httpd]# service httpd stop  #關閉web-server1服務  
  2. [root@elk ~]# curl 10.0.0.136  
  3. <html>  
  4. 10.0.0.111  
  5. </html>  
  6. [root@elk ~]# curl 10.0.0.136  
  7. <html>  
  8. 10.0.0.111  
  9. </html>  
  10. #現在只能訪問web-server2了。  
  11.   
  12. [root@kvm httpd]# service httpd start   #打開web-server1服務  
  13. [root@elk ~]# curl 10.0.0.136             
  14. <html>  
  15. 10.0.0.111  
  16. </html>  
  17. [root@elk ~]# curl 10.0.0.136  
  18. <html>  
  19. 10.0.0.137  
  20. </html>  
  21. [root@elk ~]# curl 10.0.0.136  
  22. <html>  
  23. 10.0.0.111  
  24. </html>  

7.ip_hash的負載均衡

[python] view plain copy
  1. [root@lvs-master conf.d]# cat ../nginx.conf  
  2. upstream 1.2.3.4 {  
  3.     ip_hash;  
  4.     server 10.0.0.111:80 weight=1 max_fails=2 fail_timeout=2;  
  5.     server 10.0.0.137:80 weight=1 max_fails=2 fail_timeout=2;  
  6.     }  
  7. [root@lvs-master conf.d]# service nginx restart  
  8. 停止 nginx:                                               [確定]  
  9. 正在啓動 nginx:                                           [確定]  
  10.   
  11. [root@elk ~]# curl 10.0.0.136  
  12. <html>  
  13. 10.0.0.137  
  14. </html>  
  15. [root@elk ~]# curl 10.0.0.136  
  16. <html>  
  17. 10.0.0.137  
  18. </html>  
  19. #配置這種負載均衡後,>每個請求按訪問IP的hash結果分配,這樣來自同一個IP的訪客固定訪問一個後端服務器,  
  20. #有效解決了動態網頁存在的session共享問題。(一般電子商務網站用的比較多)  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章