Nginx是一個輕量化高效能的WEB server,它可以通過本來既有Reverse Proxy(反向代理)及Nginx的HTTP Upstream模組來達到負載平衡的功能。
此模組利用排程演算法將外部收到的HTTP Request調度到後端伺服器。目前Upstream模組支援的演算法有
upstream設定範例
http{ ...... upstream 負載平衡名稱{ server www.domain.com down #用domain name方式 server 127.0.0.1:80 weight=3 fail_timeout=20s max_fails=3 #用IP方式 server unix:/var/run/nginx/backend.sock backup #unix socket 方式 } .... server{ ... location / {....} } }
server 後面用3種方式(domain name,ip:port,unix socket)指定後端伺服器以外,還可以加上一些參數。以下說明參數使用的時機
假設Client端IP:192.168.50.200 CIP
負載平衡器對外虛擬IP:192.168.50.80 VIP
負載平衡器對內調度使用的IP:192.168.60 NIP
Nginx Web1 and Nginx Web2 為 SIP
來原:目的 CIP ->VIP
處理Client Http Requset Header 及 利用排程演算法調度哪一個後端的SIP
來原:目的 NIP ->SIP
來原:目的 SIP ->NIP
處理後端伺服器SIP Http Respone Header
來原:目的 VIP->CIP
user nobody; worker_processes 4; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { use epoll; worker_connections 512; } http{ ...... upstream webDRBL{ server 192.168.60.1:80 weight=3; server 192.168.60.2:80 weight=1; } server{ listen 80; server_name localhost; root /var/www/html; access_log /var/log/nginx/localhost-access.log main; error_log /var/log/nginx/localhost-error.log; location ~* \.(htm|html)$ { proxy_pass http://webDRBL; } #error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } }
因Nginx Web1 或Nginx Web2 設定檔大至一樣,只列其中一個後端服務設定檔。或是不用參考以下設定,這只是一般Web設定檔,簡單的話可以參考官網完整示例
http { server { listen 80; server_name localhost; root /var/www/html; access_log /var/log/nginx/localhost-access.log main; error_log /var/log/nginx/localhost-error.log; # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 location ~ \.php$ { #error_page 404 /404.html; if (!-f $request_filename) { return 404; } fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; } #error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } }
另外,在Nginx Web1 and Nginx Web2 放置 /var/www/html/test.html
Hello :Nginx 192.168.60.1
Hello :Nginx 192.168.60.2
觀察 Nginx Web1 的log檔(/var/log/nginx/localhost-access.log)。發現來源IP是負載平衡器內部調度的NIP
192.168.60.80 - - [12/Oct/2013:12:01:49 +0800] "GET /test.html HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.69 Safari/537.36" "192.168.50.200" - - 0.000
假若要顯示外部Client IP cip,就必須使用Http Proxy標準模組 proxy_set_Header指令,在Nginx負載平衡器反向代理時增加Header表頭資訊X-Forwarded-For, 使後端伺服器可以獲得外部client IP cip
在Server 處增加proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
user nobody; worker_processes 4; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { use epoll; worker_connections 512; } http{ ...... upstream webDRBL{ server 192.168.60.1:80 weight=3; server 192.168.60.2:80 weight=1; } server{ listen 80; server_name localhost; root /var/www/html; access_log /var/log/nginx/localhost-access.log main; error_log /var/log/nginx/localhost-error.log; location ~* \.(htm|html)$ { proxy_pass http://webDRBL; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } #error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } }
增加的部分是 log_format 及real_ip_header
http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" - $upstream_response_time $request_time '; set_real_ip_from 192.168.60.0/24; #設定可信的代理伺服器IP清單 real_ip_header X-Real-IP; real_ip_header X-Forwarded-For; #顯示未在可信的代理伺服器IP清單的IP server { listen 80; server_name localhost; root /var/www/html; access_log /var/log/nginx/localhost-access.log main; error_log /var/log/nginx/localhost-error.log; # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 location ~ \.php$ { #error_page 404 /404.html; if (!-f $request_filename) { return 404; } fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; } #error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } }
再觀察 Nginx Web1 的log檔(/var/log/nginx/localhost-access.log)看看。
192.168.50.200 - - [12/Oct/2013:13:15:45 +0800] "GET /test.html HTTP/1.0" 200 26 "-" "Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Firefox/24.0" "192.168.50.200" - - 0.001