======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.1
Hello :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大原則-高俊峰著-佳魁資訊]]