======Nginx負載平衡器====== Nginx是一個輕量化高效能的WEB server,它可以通過本來既有Reverse Proxy(反向代理)及Nginx的HTTP Upstream模組來達到負載平衡的功能。 ======Http Upstream模組====== 此模組利用排程演算法將外部收到的HTTP Request調度到後端伺服器。目前Upstream模組支援的演算法有 * 輪詢(round-robin 預設) * ip_hash * fair * url_hash 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**)指定後端伺服器以外,還可以加上一些參數。以下說明參數使用的時機 * weight:指定輪詢的權重,weight的值越大,此後端伺服器被分配到存取機率越大。 * down:此後端伺服器目前不參與負載平衡中。 * backup:當其他後端伺服器出現故障或忙碌時,才會呼叫此後端伺服器。 * max_fails:此參數預設是1。當超過最大次數時,傳回proxy_next_upstream模組定義的錯誤。 * fail_timeout:經歷max_fails次失敗後,暫停服務時間。 ======負載平衡架構圖====== {{:linux:web:nginx負載平衡lab架構圖.png|}} 上圖是此LAB的架構圖。圖中為了說明client端->負載平衡器->後端伺服器運作情況,有三個區塊分別用圓圈表示: =====client端->負載平衡器->後端伺服器===== 假設Client端IP:192.168.50.200 CIP 負載平衡器對外虛擬IP:192.168.50.80 VIP 負載平衡器對內調度使用的IP:192.168.60 NIP Nginx Web1 and Nginx Web2 為 SIP - client端->負載平衡器來原:目的 CIP ->VIP - 負載平衡器處理Client Http Requset Header 及 利用排程演算法調度哪一個後端的SIP - 負載平衡器->後端伺服器來原:目的 NIP ->SIP =====client端<-負載平衡器<-後端伺服器===== - 後端伺服器->負載平衡器來原:目的 SIP ->NIP - 負載平衡器處理後端伺服器SIP Http Respone Header - 負載平衡器->client端來原:目的 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 Web後端伺服器設定檔====== 因Nginx Web1 或Nginx Web2 設定檔大至一樣,只列其中一個後端服務設定檔。或是不用參考以下設定,這只是一般Web設定檔,簡單的話可以參考官網[[http://wiki.nginx.org/NginxChsFullExample|完整示例]] 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.1Hello :Nginx 192.168.60.2 ======利用Http Proxy標準模組指令 proxy_set_Header====== 觀察 Nginx Web1 的log檔(/var/log/nginx/localhost-access.log)。發現來源IP是負載平衡器內部調度的NIP192.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 ======參考資料====== - [[http://wiki.nginx.org/NginxChs|Chs_Nginx]] - [[http://wiki.nginx.org/Configuration|官方Nginx]] - [[http://findbook.tw/book/9789865836030/price|伺服器加速營運14大原則-高俊峰著-佳魁資訊]]