天天看點

Nginx4大子產品——proxy、headers、upstream、stream

  

一:ngx_http_proxy_module

       反向代理( reverse proxy) 方式是指用代理伺服器來接受 Internet 上的連接配接請求, 然後将請求轉發給内部網絡中的上遊伺服器, 并将從上遊伺服器上得到的結果傳回給 Internet 上請求連接配接的用戶端, 此時代理伺服器對外的表現就是一個 Web 伺服器。 充當反向代理伺服器也是 Nginx 的一種常見用法( 反向代理伺服器必須能夠處理大量并發請求), 下面将介紹Nginx作為 HTTP 反向代理伺服器的基本用法。由于Nginx具有“強悍”的高并發高負載能力, 是以一般會作為前端的伺服器直接向用戶端提供靜态檔案服務。 但也有一些複雜、 多變的業務不适合放到 Nginx 伺服器上, 這時會用Apache、 Tomcat 等伺服器來處理。 于是, Nginx 通常會被配置為既是靜态Web伺服器也是反向代理伺服器( 如下圖所示), 不适合Nginx處理的請求就會直接轉發到上遊伺服器中處理。

Nginx4大子產品——proxy、headers、upstream、stream

ngx_http_proxy_module子產品允許傳送請求到其它伺服器,也就是做反向代理。下面提供一個基本的配置示例:

location / {
  root /usr/share/nginx/html;
  proxy_redirect default;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_connect_timeout 2;
  proxy_send_timeout 5;
  proxy_read_timeout 5;
  proxy_buffer_size 256k;
  proxy_buffers 4 256k;
  proxy_busy_buffers_size 256k;
  proxy_pass http://127.0.0.1:80;
}      

ngx_http_proxy_module子產品常用指令解釋:

1)proxy_bind

Syntax: proxy_bind address [transparent] | off;
Default: —
Context: http, server, location
This directive appeared in version 0.8.22.      

  在調用connect()前将上遊socket綁定到一個本地位址,如果主機有多個網絡接口或别名,但是你希望代理的連接配接通過指定的接口或位址,可以使用這個指令。

  透明傳輸模式允許傳出連接配接到代理伺服器起源于一個非本地IP位址,例如,從一個真實的IP位址的用戶端 ︰

proxy_bind $remote_addr transparent;      

  為了使此參數工作,就必須以超級使用者的特權運作nginx的工作程序和配置核心路由表攔截來自代理伺服器的網絡流量。

2)proxy_buffer_size

Syntax:    proxy_buffer_size size;
Default:proxy_buffer_size 4k|8k;
Context:http, server, location      

  設定緩沖區的大小為size,nginx從被代理的伺服器讀取響應時,使用該緩沖區儲存響應的開始部分。這部分通常包含着一個小小的響應頭。該緩沖區大小預設等于proxy_buffers指令設定的一塊緩沖區的大小,但它也可以被設定得更小。

3)proxy_buffers

Syntax:    proxy_buffers number size;
Default:proxy_buffers 8 4k|8k;
Context:http, server, location      

  設定用于讀取應答(來自被代理伺服器)的緩沖區數目和大小,為每個連接配接設定緩沖區的數量是number參數,每塊緩沖區的大小是size參數。這些緩沖區用于儲存從被代理的伺服器讀取的響應。每塊緩沖區預設等于一個記憶體頁的大小。這個值預設是4K還是8K,取決于平台。

4)proxy_buffering

Syntax:    proxy_buffering on | off;
Default:proxy_buffering on;
Context:http, server, location      

  代理的時候,開啟或關閉緩沖後端伺服器的響應。

  當開啟緩沖時,nginx盡可能快地從被代理的伺服器接收響應,再将它存入proxy_buffer_size和proxy_buffers指令設定的緩沖區中。

  如果響應無法整個納入記憶體,那麼其中一部分将存入磁盤上的臨時檔案。proxy_max_temp_file_size和proxy_temp_file_write_size指令可以控制臨時檔案的寫入。

  當關閉緩沖時,收到響應後,nginx立即将其同步傳給用戶端。nginx不會嘗試從被代理的伺服器讀取整個請求,而是将proxy_buffer_size指令設定的大小作為一次讀取的最大長度。

  響應頭“X-Accel-Buffering”傳遞“yes”或“no”可以動态地開啟或關閉代理的緩沖功能。 這個能力可以通過proxy_ignore_headers指令關閉。

5)proxy_busy_buffers_size

Syntax:    proxy_busy_buffers_size size;
Default:proxy_busy_buffers_size 8k|16k;
Context:http, server, location      

  當開啟緩沖響應的功能以後,在沒有讀到全部響應的情況下,寫緩沖到達一定大小時,nginx一定會向用戶端發送響應,直到緩沖小于此值。

  這條指令用來設定此值。 同時,剩餘的緩沖區可以用于接收響應,如果需要,一部分内容将緩沖到臨時檔案。該大小預設是proxy_buffer_size和proxy_buffers指令設定單塊緩沖大小的兩倍。

6)proxy_max_temp_file

Syntax:    proxy_max_temp_file_size size;
Default:proxy_max_temp_file_size 1024m;
Context:http, server, location      

  打開響應緩沖以後,如果整個響應不能存放在proxy_buffer_size和proxy_buffers指令設定的緩沖區内,部分響應可以存放在臨時檔案中。 這條指令可以設定臨時檔案的最大容量。

  而每次寫入臨時檔案的資料量則由proxy_temp_file_write_size指令定義。

  将此值設定為0将禁止響應寫入臨時檔案。

7)proxy_temp_file_write_size

Syntax:    proxy_temp_file_write_size size;
Default:proxy_temp_file_write_size 8k|16k;
Context:http, server, location      

  在開啟緩沖後端伺服器響應到臨時檔案的功能後,設定nginx每次寫資料到臨時檔案的size(大小)限制。 size的預設值是proxy_buffer_size指令和proxy_buffers指令定義的每塊緩沖區大小的兩倍, 而臨時檔案最大容量由    proxy_max_temp_file_size指令設定。

8)proxy_temp_path

Syntax:    proxy_temp_path path [level1 [level2 [level3]]];
Default:proxy_temp_path proxy_temp;
Context:http, server, location      

  定義從後端伺服器接收的臨時檔案的存放路徑,可以為臨時檔案路徑定義至多三層子目錄的目錄樹。 比如,下面配置

proxy_temp_path /spool/nginx/proxy_temp 1 2;        

       那麼臨時檔案的路徑看起來會是這樣:

/spool/nginx/proxy_temp/7/45/00000123457      

9)proxy_connect_timeout

Syntax:    proxy_connect_timeout time;
Default:proxy_connect_timeout 60s;
Context:http, server, location      

設定與後端伺服器建立連接配接的逾時時間,應該注意這個逾時一般不可能大于75秒。預設為60s,建議生産環境連接配接時間設定為1到2s。

10)proxy_http_version

Syntax:    proxy_http_version 1.0 | 1.1;
Default:proxy_http_version 1.0;
Context:http, server, location
This directive appeared in version 1.1.4.      

  設定代理使用的HTTP協定版本,預設使用的版本是1.0,而1.1版本則推薦在使用keepalive連接配接時一起使用。我接觸的生産環境中都是設定http 1.1版本了。

11)proxy_ignore_client_abort

Syntax:    proxy_ignore_client_abort on | off;
Default:proxy_ignore_client_abort off;
Context:http, server, location      

  決定當用戶端在響應傳輸完成前就關閉連接配接時,nginx是否應關閉後端連接配接。

12)proxy_pass

Syntax:    proxy_pass URL;
Default:—
Context:location, if in location, limit_except      

  設定後端伺服器的協定和位址,還可以設定可選的URI以定義本地路徑和後端伺服器的映射關系。 這條指令可以設定的協定是“http”或者“https”,而位址既可以使用域名或者IP位址加端口(可選)的形式來定義:

proxy_pass http://localhost:8000/uri/;      

  對于URI可選,一般情況下使用是不需要指定的,除非你需要的通路方式就是這樣的。

  也可以使用UNIX域套接字路徑來定義,該路徑接在“unix”字元串後面,兩端由冒号所包圍,比如:

proxy_pass http://unix:/tmp/backend.socket:/uri/;      

  如果proxy_pass沒有使用URI,傳送到後端伺服器的請求URI一般用戶端發起的原始URI,如果nginx改變了請求URI,則傳送的URI是nginx改變以後的完整規範化URI:

location /path/ {
  proxy_pass http://127.0.0.1;
}      

  如果proxy_pass使用了URI(/也算),當傳送請求到後端伺服器時,規範化以後的請求路徑(原始請求URI)與location配置中的路徑的比對部分将被替換為proxy_pass指令中定義的URI,其實這種實作方式就是做虛拟路徑代理,配置方式如下:

location /path/ {
  proxy_pass http://127.0.0.1/;
}      

  虛拟路徑代理就是,比如說通路”http://127.0.0.1/path/uri”位址,當比對到這個location之後,通過”proxy_pass http://127.0.0.1/”代理到後端時,一個新的URL就成了”http://127.0.0.1/uri”這樣。

  其中的/path就稱為虛拟路徑,虛拟給使用者的,後端沒有真正的/path路徑,這裡要特别注意”proxy_pass http://127.0.0.1/”最後的”/”,如果沒有這個”/”那麼通路就會出現404,因為你沒有給proxy_pass定義URI,是以不存在将規範化以後的請求路徑(原始請求URI)與location配置中的路徑的比對部分将被替換為proxy_pass指令中定義的URI這一說法,切記。Nginx實作虛拟路徑代理

注意

  當使用一個正規表達式(~或~*)指定localtion時,在這種情況下,proxy_pass應該是一個沒有URI的指令,如果指定了URI,那麼代理到後端時,URI會被去掉,進而變成了http://127.0.0.1/some/path,也就是說原始通路URI不會做任何改變傳送到後端。

  還有一種情況,當URI使用rwrite重寫指令後,在這種情況下,proxy_pass應該是一個沒有URI的指令,如果指定了URI,那麼代理到後端時,URI會被去掉,進而變成了http://127.0.0.1/some/path。

rewrite /name/([^/]+) /users?name=$1 break;      

  最後,這種以代理的工作方式,一般都會使用到Nginx upstream,以此來做負載均衡。這種情況下直接給定一個upstream的名稱即可(需要先定義一個upstream),如下:

location / {
upstream test{
127.0.0.1:80;
}
proxy_pass http://test;
}      

13)proxy_next_upstream

Syntax:    proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | 
http_403 | http_404 | non_idempotent | off ...;
Default:proxy_next_upstream error timeout;
Context:http, server, location      

  當你使用Nginx proxy代理時,如果是代理到後端是使用upstream,那麼這個指令就是指定在何種情況下,一個失敗的請求應該被發送到下一台後端伺服器,有如下指令:

  error – 和後端伺服器建立連接配接時,或者向後端伺服器發送請求時,或者從後端伺服器讀取響應時,出現錯誤;

  timeout – 和後端伺服器建立連接配接時,或者向後端伺服器發送請求時,或者從後端伺服器讀取響應時,出現逾時;

  invalid_header – 後端伺服器傳回空響應或者非法響應頭;

  http_500 – 後端伺服器傳回的響應狀态碼為500;

  http_502 – 後端伺服器傳回的響應狀态碼為502;

  http_503 – 後端伺服器傳回的響應狀态碼為503;

  http_504 – 後端伺服器傳回的響應狀态碼為504;

  http_404 – 後端伺服器傳回的響應狀态碼為404;

  off – 關閉proxy_next_upstream功能—出錯就選擇另一台上遊伺服器再次轉發。

  需要了解一點的是,隻有在沒有向用戶端發送任何資料以前,将請求轉給下一台後端伺服器才是可行的。也就是說,如果在傳輸響應到用戶端時出現錯誤或者逾時,這類錯誤是不可能恢複的。

  另外Nginx1.7開始提供了将請求傳遞給下一台伺服器可以通過重試的次數和時間進行限制。

14)proxy_next_upstream_timeout

Syntax:    proxy_next_upstream_timeout time;
Default:proxy_next_upstream_timeout 0;
Context:http, server, location
This directive appeared in version 1.7.5.      

  限制了重試請求可以被傳遞給下一台伺服器的時間,預設值為0将關閉這一限制。

15)proxy_next_upstream_tries

Syntax:    proxy_next_upstream_tries number;
Default:proxy_next_upstream_tries 0;
Context:http, server, location
This directive appeared in version 1.7.5.      

  限制了重試請求可以被傳遞給下一台伺服器的次數,預設值為0将關閉這一限制。

16)proxy_read_timeout

Syntax:    proxy_read_timeout time;
Default:proxy_read_timeout 60s;
Context:http, server, location      

  定義從後端伺服器讀取(接收)資料的逾時時間(Nginx從用戶端接收到請求,然後把資料包轉發到後端伺服器,後端伺服器處理完請求後傳回給Nginx伺服器,Nginx接收後端資料包稱為一次read),此逾時是指相鄰兩次讀操作之間的最長時間間隔,而不是整個響應傳輸完成的最長時間。如果後端伺服器在逾時時間段内沒有傳輸任何資料,連接配接将被關閉。預設時間為60s,建議值為2-4s。

17)proxy_send_timeout

Syntax:    proxy_send_timeout time;
Default:proxy_send_timeout 60s;
Context:http, server, location      

  定義向後端伺服器發送一次資料包的逾時時間(Nginx從用戶端接收到請求,然後把資料包轉發到後端伺服器稱為一次send),此逾時是指相鄰兩次寫操作之間的最長時間間隔,而不是整個請求傳輸完成的最長時間。

  如果再向後端伺服器發送資料包時,超過了逾時時間的設定,那麼連接配接将被關閉。預設時間為60s,建議值為2-4s。

18)proxy_set_header

Syntax:    proxy_set_header field value;
Default:proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context:http, server, location      

  允許重新定義或者添加發往後端伺服器的請求頭。value可以包含文本、變量或者它們的組合。 當且僅當目前配置級别中沒有定義proxy_set_header指令時,會從上面的級别繼承配置。 預設情況下,隻有兩個請求頭會被重新定義:

proxy_set_header Host $proxy_host;
proxy_set_header Connection close;      

  如果不想改變請求頭“Host”的值,可以這樣來設定:

proxy_set_header Host $http_host;      

  但是,如果用戶端請求頭中沒有攜帶這個頭部,那麼傳遞到後端伺服器的請求也不含這個頭部。 這種情況下,更好的方式是使用$host變量——它的值在請求包含“Host”請求頭時為“Host”字段的值,在請求未攜帶“Host”請求頭時為虛拟主機的主域名:

proxy_set_header Host $host;      

  此外,伺服器名可以和後端伺服器的端口一起傳送:

proxy_set_header Host $host:$proxy_port;      

  如果某個請求頭的值為空,那麼這個請求頭将不會傳送給後端伺服器:

proxy_set_header Accept-Encoding "";      

  $proxy_add_x_forwarded_for内置變量,将$remote_addr變量值添加在用戶端“X-Forwarded-For”請求頭的後面,并以逗号分隔。

   如果用戶端請求未攜帶“X-Forwarded-For”請求頭,$proxy_add_x_forwarded_for變量值将與$remote_addr變量相同。

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;      

19)proxy_pass_header

Syntax:    proxy_pass_header field;
Default:—
Context:http, server, location      

  允許指定跳過某些字段從代理伺服器到用戶端,一般用在CDN中傳回來的字段資訊,但不需要傳回到後端伺服器,就可以使用proxy_pass_header指令跳過。

20)proxy_redirect

Syntax:    proxy_redirect default;
proxy_redirect off;
proxy_redirect redirect replacement;
Default:proxy_redirect default;
Context:http, server, location      

  設定後端伺服器“Location”響應頭和“Refresh”響應頭的替換文本。 假設後端伺服器傳回的響應頭是 “Location: http://localhost:8000/two/some/uri/”,那麼指令

proxy_redirect http://localhost:8000/two/ http://frontend/one/;      

  将把字元串改寫為 “Location: http://frontend/one/some/uri/”。

  replacement字元串可以省略伺服器名:

proxy_redirect http://localhost:8000/two/ /;      

  此時将使用代理伺服器的主域名和端口号來替換。如果端口是80,可以不加。

  用default參數指定的預設替換使用了location和proxy_pass指令的參數。是以,下面兩例配置等價:

location /one/ {
proxy_pass http://upstream:port/two/;
proxy_redirect default;
}      
location /one/ {
  proxy_pass http://upstream:port/two/;
  proxy_redirect http://upstream:port/two/ /one/;
}      

而且因為同樣的原因,proxy_pass指令使用變量時,不允許本指令使用default參數。

replacement字元串可以包含變量:

proxy_redirect http://localhost:8000/ http://$host:$server_port/;      

而redirect字元串從1.1.11版本開始也可以包含變量:

proxy_redirect http://$proxy_host:8000/ /;      

同時,從1.1.11版本開始,指令支援正規表達式。使用正規表達式的話,如果是大小寫敏感的比對,redirect以“~”作為開始,如果是大小寫不敏感的比對,redirect以“~*”作為開始。而且redirect的正規表達式中可以包含命名比對組和位置比對組,而在replacement中可以引用這些比對組的值:

proxy_redirect ~^(http://[^:]+):\d+(/.+)$ $1$2;
proxy_redirect ~*/user/([^/]+)/(.+)$ http://$1.example.com/$2;      

除此以外,可以同時定義多個proxy_redirect指令:

proxy_redirect default;
proxy_redirect http://localhost:8000/ /;
proxy_redirect http://www.example.com/ /;      

另外,off參數可以使所有相同配置級别的proxy_redirect指令無效:

proxy_redirect off;
proxy_redirect default;
proxy_redirect http://localhost:8000/ /;
proxy_redirect http://www.example.com/ /;      

二:ngx_http_upstream_module

執行個體

upstream appservers {  
    zone appservers 64k;  
    #預設權重為1
    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;  
    }  
}       

  1.weight

=

number

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

  2.max_fails

number

  設定Nginx與伺服器通信的嘗試失敗的次數。

  3.fail_timeout

time

  設定

  • 統計失敗嘗試次數的時間段。在這段時間中,伺服器失敗次數達到指定的嘗試次數,伺服器就被認為不可用。
  • 伺服器被認為不可用的時間段。

  預設情況下,該逾時時間是10秒。

backup

标記為備用伺服器。當主伺服器不可用以後,請求會被傳給這些伺服器。

  4.down

  标記伺服器永久不可用,可以跟

ip_hash

指令一起使用。

  5.route

string

  設定伺服器路由名稱。

1.ip_hash

  該指令通過IP位址的哈希值確定用戶端均勻的連接配接所有伺服器,鍵值基于c類位址

  如果需要暫時删除其中一台伺服器,則應該使用該

down

參數進行标記,以便保留用戶端IP位址的目前散列。

2.keepalive connections

  該

connections

參數設定保留在每個輔助程序緩存中的上遊伺服器的空閑保持連接配接的最大數量。當這個數字被超過時,最近最少使用的連接配接被關閉。

  對于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 "";
        ...
    }
}      

3.least_conn

   指定伺服器組的負載均衡方法,根據其權重值,将請求發送到活躍連接配接數最少的那台伺服器。 如果這樣的伺服器有多台,那就采取有權重的輪轉法進行嘗試。

繼續閱讀