使用者工具

網站工具


linux:web:nginx_upstream

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次失敗後,暫停服務時間。

負載平衡架構圖

上圖是此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

  1. client端→負載平衡器
    來原:目的 CIP ->VIP
  2. 負載平衡器
    處理Client Http Requset Header 及 利用排程演算法調度哪一個後端的SIP 
  3. 負載平衡器→後端伺服器
    來原:目的 NIP ->SIP

client端<-負載平衡器<-後端伺服器

  1. 後端伺服器→負載平衡器
    來原:目的 SIP ->NIP
  2. 負載平衡器
    處理後端伺服器SIP Http Respone Header
  3. 負載平衡器→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 {
 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是負載平衡器內部調度的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

參考資料

linux/web/nginx_upstream.txt · 上一次變更: 2013/10/12 18:57 (外部編輯)