天天看點

Nginx 負載均衡子產品 ngx_http_upstream_module 詳述

譯序:截至發稿時止,官方最新 ngx_http_upstream_module 指令詳述。官方随時在更新,請及時關注官網最新公布。以下是官方原文。

ngx_http_upstream_module 子產品用于定義可以被

​​​ proxy_pass​​​、

​​​fastcgi_pass​​​ 以及

​​​memcached_pass​​​ 等指令引用的伺服器群。

配置示例

upstream backend {
    server backend1.example.com       weight=5;
    server backend2.example.com:8080;
    server unix:/tmp/backend3;

    server backup1.example.com:8080   backup;
    server backup2.example.com:8080   backup;
}

server {
    location / {
        proxy_pass http://backend;
    }
}      

動态可配置群,僅作為我們

​​商業訂閱​​的一部分:

upstream appservers {
    zone appservers 64k;

    server appserv1.example.com      weight=5;
    server appserv2.example.com:8080 fail_timeout=5s slow_start=30s;
    server 192.0.2.1                 max_fails=3;

    server reserve1.example.com:8080 backup;
    server reserve2.example.com:8080 backup;
}

server {
    location / {
        proxy_pass http://appservers;
        health_check;
    }

    location /upstream_conf {
        upstream_conf;
        allow 127.0.0.1;
        deny all;
    }
}      

指令

文法:upstream name { ... }

 預設值:—

上下文:http

定義一群伺服器。伺服器可以監聽到不同的端口。此外,監聽 TCP 和 UNIX-domian socket 的伺服器可以混合定義。

例如:

upstream backend {
    server backend1.example.com weight=5;
    server 127.0.0.1:8080       max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend3;
}      

預設情況下,請求是使用一個權重重的循環負載方法配置設定給各個主機的。在上面的例子中,每七個請求會以以下方案進行配置設定:五個請求分給 backend1.example.com 而另外兩個請求分别配置設定給第二和第三個主機。如果在連接配接一台主機時發生錯誤,目前請求會被傳給下一台主機,如此這般知道所有運作中的伺服器都被嘗試。如果沒有任何主機成功傳回,用戶端會受到從最後一台主機傳回的通信結果。

文法:server address [parameters];

預設值:—

上下文:upstream

定義一台主機的位址以及其他一些參數。位址可以被指定為一個域名或一個 IP 位址,端口号參數可選,或者被指定為 "unix:" 字首之後的一個 UNIX-domain socket 路徑。端口号沒指定的話就使用端口号 80。解析到多個 IP 位址的域名會一次性定義多台主機。

可以定義以下參數:

weight=number

        設定伺服器的權重,預設為 1。

max_fails=number

        設定由 fail_timeout 定義的時間段内連接配接該主機的失敗次數,以此來斷定 fail_timeout 定義的時間段内該主機是否可用。預設情況下這個數值設定為 1。零值的話禁用這個數量的嘗試。由

​​proxy_next_upstream​​、

​​fastcgi_next_upstream​​、以及

​​memcached_next_upstream​​ 等指令來判定錯誤嘗試。

fail_timeout=time

        設定

        在指定時間内連接配接到主機的失敗次數,超過該次數該主機被認為不可用。

        伺服器被視為無效的時段。

        這個參數預設是 10 秒鐘。

slow_start=time

        設定一台不健康的主機變成

​​健康​​主機,或者當一台主機在被認為不可用變成可用時,将其權重由零恢複到标稱值的時間。預設值為零,也就是說,禁用慢啟動。

這個功能僅作為我們的​​商業訂閱​​的一部分。

backup

        将目前伺服器标記為備份伺服器。當主伺服器不可用時,向備用伺服器傳遞請求。

down

        标記目前伺服器為永不可用;和

​​ ip_hash​​ 指令一起使用。

舉例:

upstream backend {
    server backend1.example.com     weight=5;
    server 127.0.0.1:8080           max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend3;

    server backup1.example.com:8080 backup;
}      

如果群裡面隻有一台主機,那麼 max_fails、 fail_timeout 和 slow_start 參數将被忽略,而且這樣的主機也永遠不會被認為不可用。

文法:zone name size;

預設值:—

上下文:upstream

使群動态可配。定義持有群的配置和工作程序之間共享的運作時狀态的共享記憶體區域的名字和大小。這樣的群允許在運作時添加、删除和修改伺服器。這個配置通過

​​ upstream_conf​​ 進行通路。

這一指令僅作為我們​​商業訂購​​的一部分。

文法:ip_hash;

預設值:—

上下文:upstream

指定一個使用負載均衡方法根據用戶端 IP 位址将請求分發給一些伺服器的群。客戶 IPv4 位址或者 IPv6 位址的前三個位群作為一個散列鍵。這個方法可以使同一個用戶端的常常被發送給同一台主機,除非這台主機是不可用狀态。在這種情況下(該主機不可用)用戶端請求會被傳遞到另一台主機。大多數情況下,它将被發送給同一台主機。

Nginx 1.3.2 和 1.2.2 之後開始支援 IPv6 位址。

如果伺服器中的一台需要臨時移除掉,那麼它應該使用 down 參數标記以保持客戶 IP 位址的目前散列。

例如:

upstream backend {
    ip_hash;

    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com down;
    server backend4.example.com;
}      

在 Nginx 1.3.1 和 1.2.2 版本之前的版本是無法使用 ip_hash 負載均衡方式定義伺服器權重的。

文法:keepalive connections;

預設:—

上下文:upstream

這一指令在 Nginx 版本 1.1.4 之後出現。

激活 upstream 伺服器的連接配接緩存。

connections 參數設定儲存在每個工作程序緩存中的 upstream 主機的閑置 keepalive 連接配接的最大個數。超出這個數目時,最近很少使用的連接配接被關閉。

應該特别指出的是 keepalive 指令并沒有限制一個 Nginx 工作程序所能承載的連接配接總量。connections 應該設定為一個足夠小的值以使 upstream 伺服器也足以應對新的連接配接。

帶有 keepalive 連接配接的 memcached upstream 配置例子:

upstream memcached_backend {
    server 127.0.0.1:11211;
    server 10.0.0.2:11211;

    keepalive 32;
}

server {
    ...

    location /memcached/ {
        set $memcached_key $uri;
        memcached_pass memcached_backend;
    }

}      

對于 HTTP,

​​proxy_http_version​​ 指令應該設定為 "1.1",并且清空 "Connection" 頭字段:

upstream http_backend {
    server 127.0.0.1:8080;

    keepalive 16;
}

server {
    ...

    location /http/ {
        proxy_pass http://http_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        ...
    }
}      

作為一種選擇,HTTP/1.0 持久連接配接可以通過傳遞 "Connection: Keep-Alive" 頭字段到 upstream 伺服器來使用,雖然這種方法并不被推薦。

對于 FastCGI 伺服器,需要為持久連接配接設定

​​ fastcgi_keep_conn​​:

upstream fastcgi_backend {
    server 127.0.0.1:9000;

    keepalive 8;
}

server {
    ...

    location /fastcgi/ {
        fastcgi_pass fastcgi_backend;
        fastcgi_keep_conn on;
        ...
    }
}      

當使用 round-robin 之外的負載均衡方法時,需要在 keepalive 指令之前将他們激活。

SCGI 和 uwsgi 協定沒有長連接配接的概念。

文法:least_conn;

預設值:—

上下文:upstream

描述:這一指令出現在版本 1.3.1 和 1.2.2 中。

定義一群應該在請求傳遞給具有最小有效連接配接的伺服器時使用的負載均衡方法,要考慮到伺服器的權重。如果有很多這樣的伺服器,将會使用帶權重的 round-robin 方法。

文法:health_check [interval=time] [fails=number] [passes=number] [uri=uri] [match=name];

預設值:—

上下文:location

        激活定期健康檢查。

支援以下可選參數:

  • interval:兩次連續性健康檢查的間隔時間,預設為 5 秒;
  • fails:設定連續性健康檢查失敗的次數,超過這個次數的話這台伺服器就被認為是不健康的,預設為 1;
  • passes:設定連續性健康檢查通過的次數,超過這個次數的話這台伺服器就被認為是健康的,預設為 1;
  • uri:定義健康檢查請求用的 URI,預設為 "/";
  • match:定義健康檢查傳回通過的比對塊的配置;預設情況下,傳回應該具有狀态碼 2XX 或者 3XX。

例如,

location / {
    proxy_pass http://backend;
    health_check;
}      

将會每隔五秒鐘發送 "/" 到 backend 群的每個伺服器。如果有任何通信錯誤或者逾時發生,或者代理伺服器傳回為 2XX 或者 3XX 之外的狀态碼,健康檢查失敗,這台伺服器就被認為是不健康的了。來自用戶端的請求不會被傳遞給不健康的伺服器。

健康檢查可以被配置成測試傳回的狀态碼,頭字段以及其值,還有正文内容。測試單獨地使用 match 參數引用到的

​​ match​​ 指令進行配置,例如:

http {
    server {
    ...
        location / {
            proxy_pass http://backend;
            health_check match=welcome;
        }
    }

    match welcome {
        status 200;
        header Content-Type = text/html;
        body ~ "Welcome to nginx!";
    }
}      

這一配置說明了健康檢查通過的條件是,健康檢查請求應該成功傳回,擁有狀态碼 200,Content-Type 是為 "text/html",并且在正文中包含 "Welcome to nginx!"。

伺服器群必須屬于

​​共享記憶體​​。

如果一些健康檢查是為同一群伺服器而定義,一個失敗的任何檢查就會使相關伺服器被認為是不健康的。

這個指令僅作為我們的​​商業訂閱​​的一部分。

文法:match name { ... }

預設值:—

上下文:http

定義已命名測試設定,用于核對健康檢查請求的傳回。

可以在一個傳回中進行以下項目測試:

status 200;

狀态碼為 200。

status ! 500;

狀态碼不是 500。

status 200 204;

狀态碼為 200 或者 400。

status ! 301 302;

狀态碼既不是 301 也不是 302。

status 200-399;

狀态碼在 200 - 399 之間。

status ! 400-599;

狀态碼不在 400 - 599 之間。

status 301-303 307;

狀态碼是 301,302,303,或者 307。

header Content-Type = text/html;

頭包含字段 "Content-Type" 值為 text/html。

header Content-Type != text/html;

頭包含字段 "Content-Type" 值不是 text/html。

header Connection ~ close;

頭包含字段 "Connection" 值比對正規表達式 close。

header Connection !~ close;

頭包含字段 "Connection" 值不比對正規表達式 close。

header Host;

頭包含字段 "Host"。

header ! X-Accel-Redirect;

頭沒有 "X-Accel-Redirect" 字段。

body ~ "Welcome to nginx!";

正文比對正規表達式 "Welcome to nginx!"。

body !~ "Welcome to nginx!";

正文不比對正規表達式 "Welcome to nginx!"。

如果以上有些被定義,那麼傳回必須全都比對時才能說明它測試通過。

僅僅檢查傳回正文的頭 256 k 個位元組。

例如:

# status is 200, content type is "text/html",
# and body contains "Welcome to nginx!"
match welcome {
    status 200;
    header Content-Type = text/html;
    body ~ "Welcome to nginx!";
}
# status is not one of 301, 302, 303, or 307, and header does not have "Refresh:"
match not_redirect {
    status ! 301-303 307;
    header ! Refresh;
}
# status ok and not in maintenance mode
match server_ok {
    status 200-399;
    body !~ "maintenance mode";
}      

這個指令僅作為我們的​​商業訂閱​​的一部分。

文法:sticky cookie name [expires=time] [domain=domain] [path=path];

sticky route variable ...;

預設值:—

上下文:upstream

這一指令開始出現于版本 1.5.7。

激活會話關聯,可以使來自同一用戶端的請求總是傳遞給一群伺服器中的同一個。例如:

upstream backend {
    server backend1.example.com;
    server backend2.example.com;

    sticky_cookie_insert srv_id expires=1h domain=example.com path=/;
}      

沒有綁定到特定伺服器的用戶端請求會被傳遞到由配置的負載均衡方法選中的伺服器。這個用戶端的而後的請求将被傳遞到同一台伺服器。如果指定伺服器無法處理請求,一台新的伺服器會被選中綁定,就像這個用戶端的這次請求前沒有綁定到任何伺服器一樣。

關于綁定伺服器的資訊儲存在 HTTP cookie 中。第一個參數設定 cookie 名。其他參數如下:

expires

        設定浏覽器保持 cookie 的時間。特别值 max 将會使 cookie 在 "31 Dec 2037 23:55:55 GMT" 才過期。這個是老的浏覽器所能知道最大日期值了。如果這個參數沒有定義,cookie 會在浏覽器會話結束時過期。

domain

        定義設定的 cookie 的域名。

path

        定義設定的 cookie 的路徑。

如果任何一個參數被遺漏掉,相應的 cookie 屬性就不會被設定上。

這個指令僅作為我們的​​商業訂閱​​的一部分。

文法:upstream_conf;

預設值:—

上下文:location

開啟 location 域的 HTTP upstream 配置接口。對于這一 location 的通路應該是

​​受限​​的。

配置指令可以用于:

  • 檢視一群中的主要和備用伺服器;
  • 檢視一個特别的伺服器;
  • 修改一個特别的伺服器;
  • 添加一個新的伺服器(參考下邊注釋);
  • 移除一個特别的伺服器。

正如在 ​​ server​​ 指令中提到的那樣,指定一個伺服器作為一個域名可能導緻多個伺服器被添加到群。因為位址在一群不需要是獨特的,單個伺服器在一個群可以被唯一引用的話隻有用他們的 ID。伺服器的 ID 會被自動配置設定,并在群配置中顯示。

一個配置指令包括作為請求參數傳遞的參數,例如:

​​ http://127.0.0.1/upstream_conf?upstream=appservers

​​ 支援以下參數:

upstream=name

選擇一群。這一參數是強制必須的。

backup=

如果沒有設定,選中一群中的主要伺服器。如果設定了,則選中一群中的備用伺服器。

id=number

選中一群中特定的主要伺服器或者備用伺服器。

remove=

移調一群中一台特定的主要伺服器或者備用伺服器。

add=

添加一台主要伺服器或者備用伺服器到群。

server=address

​​ server​​ 指令中的 "address" 參數。

weight=number

​​ server​​ 指令中的 "weight" 參數。

max_fails=number

​​ server​​ 指令中的 "max_fails" 參數。

fail_timeout=time

​​ server​​ 指令中的 "fail_timeout" 參數。

slow_start=time

​​ server​​ 指令中的 "slow_start" 參數。

down=

​​ server​​ 指令中的 "down" 參數。

up=

​​ server​​ 指令中的 "down" 參數相反。

前三個參數用于選擇指令适用的對象。

比如,檢視群組裡頭的主伺服器,發送:

​​ http://127.0.0.1/upstream_conf?upstream=appservers​​

檢視群組裡頭的備用伺服器,發送:

​​ http://127.0.0.1/upstream_conf?upstream=appservers&backup=​​

檢視群組裡頭特定的主伺服器,發送:

​​ http://127.0.0.1/upstream_conf?upstream=appservers&id=42​​

檢視群組裡頭特定的備用伺服器,發送:

​​ http://127.0.0.1/upstream_conf?upstream=appservers&backup=&id=42​​

要添加一台主伺服器或者備用伺服器到群組,在 "server=" 參數中定義其位址即可。如果沒有定義其他參數,該伺服器添加後,其他參數設定為預設值(參見

​​ server​​ 指令)。

例如,添加一台新的主伺服器到群組,發送:

​​ http://127.0.0.1/upstream_conf?add=&upstream=appservers&server=127.0.0.1:8080​​

添加一台新的從伺服器到群組,發送:

​​ http://127.0.0.1/upstream_conf?add=&upstream=appservers&backup=&server=127.0.0.1:8080​​

添加一台主伺服器到群組,設定其參數非預設值,且将其标記為 "down",發送:

​​ http://127.0.0.1/upstream_conf?add=&upstream=appservers&server=127.0.0.1:8080&weight=2&max_fails=3&fail_timeout=3s&down=​​

移除群組中的一台特定主伺服器或者備用伺服器,可以使用 id= 參數将其選擇。

例如,移除群組中的一台特定主伺服器,發送:

​​ http://127.0.0.1/upstream_conf?remove=&upstream=appservers&id=42​​

移除群組中的一台特定從伺服器,發送:

​​ http://127.0.0.1/upstream_conf?remove=&upstream=appservers&backup=&id=42​​

修改群組中的一台特定的主伺服器或從伺服器,也使用 id= 參數将其選中。

例如,修改群組中一台特定主伺服器為 "down",發送:

​​ http://127.0.0.1/upstream_conf?upstream=appservers&id=42&down=​​

修改群組裡頭的一台備用伺服器位址,發送:

​​ http://127.0.0.1/upstream_conf?upstream=appservers&backup=&id=42&server=192.0.2.3:8123​​

修改群組裡頭的一台主伺服器的其他參數,發送:

​​ http://127.0.0.1/upstream_conf?upstream=appservers&id=42&max_fails=3&weight=4​​

這個指令僅作為我們的​​商業訂閱​​的一部分。

嵌入式變量

ngx_http_upstream_module 子產品支援以下嵌入式變量:

$upstream_addr

        為 UNIX-domain socket 儲存伺服器位址及端口号。如果請求處理時涉及多台伺服器,使用逗号将他們的位址進行分隔,比如 "192.168.1.1:80, 192.168.1.2:80, unix:/tmp/sock"。如果一個由 "X-Accel-Redirect" 或者

​​錯誤頁面​​ 發出的從一個伺服器群組到另一個群組的重定向發生時,不同群組之間的伺服器位址使用冒号分隔,比如 "192.168.1.1:80, 192.168.1.2:80, unix:/tmp/sock : 192.168.10.1:80, 192.168.10.2:80"。

$upstream_cache_status

        儲存通路響應緩存的狀态(版本 0.8.3)。這一狀态可以是 "MISS","BYPASS","EXPIRED","STALE","UPDATING" 或者 "HIT"。

$upstream_response_length

        儲存從 upstream 伺服器獲得的響應體長度(版本 0.7.27)位元組的長度。幾個響應長度的話使用逗号和冒号分隔,就像 $upstream_addr 中的位址那樣。

$upstream_response_time

        儲存從 upstream 伺服器獲得的響應次數,長度以毫秒的分辨率儲存,機關是秒。幾個響應次數的話使用逗号和冒号分隔,就像 $upstream_addr 中的位址那樣。

$upstream_status

        儲存從 upstream 伺服器獲得的響應碼。幾個響應碼的話使用逗号和冒号分隔,就像 $upstream_addr 中的位址那樣。

$upstream_http_...

        儲存伺服器響應頭。比如,"Server" 響應頭可以使用 $upstream_http_server 參數激活。将頭資訊轉化為參數名字的規則和以 "

​​$http_​​" 字首開始的參數規則一樣。隻儲存最後一個響應頭。

繼續閱讀