1. 程式人生 > >Nginx4大模塊——proxy、headers、upstream、stream模

Nginx4大模塊——proxy、headers、upstream、stream模

這樣的 內容 IE 希望 har cda evel file data

一:ngx_http_proxy_module

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

技術分享圖片

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/ /;


Nginx4大模塊——proxy、headers、upstream、stream模