天天看點

nginx反向代理子產品配置詳解_nginx反向代理子產品

nginx反向代理子產品配置詳解_nginx反向代理子產品

文字:

proxy子產品

HTTP反向代理處理流程

proxy子產品

功能:對上遊伺服器使用http/https協定進行反向代理。

文法:proxy_pass URL;

上下文:if,if in location

URL規則

必須以http或者https開頭,接下來是域名|IP位址|Unix socket|upstream的名字。

域名和IP位址後邊可以加端口。

最後可以帶上可選的URI

URL參數中帶有URI會導緻法向上遊的URL不同

不攜帶URI,則将用戶端請求中的URL直接發送給上遊伺服器。

攜帶URI,則對使用者請求中的URL做如下操作:

将location中比對上的一段替換為該URI。

小例子:

upstreamproxyups {

server127.0.0.1:8012 weight=1;

keepalive2;

}

server{

set_real_ip_from  192.168.188.60;

real_ip_headerX-Forwarded-For;

listen8080;

location/a {

proxy_http_version1.1;

proxy_set_headerConnection"";

}

上例中,我配置上遊伺服器,傳回$uri的内容。

上邊proxy_pass的配置下:curl 192.168.188.60:8080/a/c,會輸出 uri:/a/c,會原封不動地把URI發送給上遊伺服器。

如果上邊第一個proxy_pass的注釋打開,注釋掉第二條。curl 192.168.188.60:8080/a/c,會輸出:uri:/www/c,在location中先進行URI替換,然後再發送給上遊伺服器。

根據指令修改發往上遊的請求

生成發往上遊的請求行

proxy_method指令

文法:proxy_method method;

上下文:http,server,location。

作用:設定傳給上遊伺服器的http請求的方法。

proxy_http_version

文法proxy_http_version  1.0|1.1

預設:proxy_http_version  1.0;

如果使用keepalive功能的時候,就必須使用proxy_http_version 1.1。

proxy_pass_requests_headers

作用:是否把使用者請求的頭部發給上遊。如果設定為off,那麼就不再把使用者請求的header發給上遊伺服器了。

預設:proxy_pass_requests_headers  on;

proxy_pass_requests_body

作用:是否把使用者請求的包體發給上遊。

預設:proxy_pass_requests_body  on;

proxy_set_header

預設:proxy_set_header Host  $proxy_host;  proxy_set_header  Connection close;

作用:在上邊proxy_pass_requests_headers為on的情況下,我可以自己設定傳給上遊伺服器的header的頭部内容。

proxy_set_body

作用:作用:在上邊proxy_pass_requests_body為on的情況下,我可以自己設定傳給上遊伺服器的body的内容。

小例子:

反向代理配置

upstreamproxyups {

server127.0.0.1:8012 weight=1;

}

server{

listen8080;

location/a {

proxy_methodPOST;

#               proxy_pass_request_headers off;

#               proxy_pass_request_body off;

proxy_set_headerHost'yang';

proxy_set_body'helow world';

proxy_http_version1.1;

proxy_set_headerConnection"";

}

}

上遊伺服器配置

server{

listen8012;

return200'8012 server response

uri:$uri

method:$request_method

request:$request

Host:$Host

http_name:$http_name\n';

}

執行測試指令:curl -H 'name:yudalihua' 192.168.188.60:8080/a/b

我在反向代理中設定的header能夠直接顯示出來,但是設定的body内容需要抓包才能看到,使用如下指令在8012端口抓包:tcpdump -i lo port 8012 -A -s 0  ,就能夠看到在反向代理子產品設定的body内容“hello  world”

接收使用者請求包體的方式

proxy_request_bufferring

預設:proxy_request_bufferring on;

當設定為on的情況

用戶端網速比較慢

上遊服務并發處理能力低

适應高吞吐量的場景。

當設定為off的情況

更及時的響應

降低nginx讀寫磁盤的消耗。

一旦開始發送内容,proxy_next_upstream指令失效。

client_body_buffer_size

預設:client_body_buffer_size 8k|18k

原理:

在接收header的時候,可能會接收到部分body。

判斷接收到的body是否已經是所有的body。

如果已經接收完了body,則不配置設定client_body_buffer

若剩餘待接收包體長度小于client_body_buffer_size,則僅配置設定所需要的。

否則,我們就配置設定client_body_buffer_size 大小的記憶體,用于接收用戶端的body。不管使用者的body是1G還是多大,我們都是通過這麼大小的緩存,一段一段地收。

client_body_in_single_buffer

client_max_body_size

預設:client_max_body_size  1m;

用戶端body的最大長度,預設是1M,非常小,不夠用。

作用:針對請求頭部中含有Content-length時,如果其字段超過了client_max_body_size,就傳回413錯誤。

client_body_temp_path

預設:client_body_temp_path  client_body_temp;

client_body_in_file_only

文法:client_body_in_file_only on|clean| off;

預設:client_body_in_file_only off;

如果設定為on:

那麼用戶端的請求的body會被一直儲存在檔案中,友善我們定位問題。

如果設定為off:

那麼用戶端處理完body之後,可能該檔案就被删除了。

client_body_timeout:

文法:client_body_timeout time;

預設:client_body_timeout 60s;

作用:兩次讀取body之間的最大時延,如果讀取包體超過了最大時延,傳回408錯誤。

與上遊服務建立連接配接

proxy_connect_timeout

預設:proxy_connect_timeout  60s;

和上遊建立TCP連接配接的逾時時間。

如果逾時了,上遊肯定是沒有響應的,那麼nginx會生成一個502的響應碼。

proxy_next_upstream http_502

作用:如果逾時,或者其他原因,和一個上遊伺服器建立TCP連接配接出現錯誤,那麼就選擇另一個upstream進行嘗試。

proxy_socket_keepalive

預設:proxy_socket_keepalive  off;

作用:反向代理和上遊服務是否開啟TCP的keepalive功能。

上下文:http,server,location。

TCP的keepalive

判斷TCP連接配接的對方是否存在,如果不存在,就及時關閉,減少資源的浪費。

keepalive

文法:keepalive connections

上下文:upstream

keepalive_requests

文法:keepalive_requests number;

預設:keepalive_requests 100;

上下文:upstream

proxy_bind

文法:proxy_bind  address [transparent] |off;

address

address可以使用變量,例如$remote_addr

address可以使用非本機位址,但是必須加上transparent關鍵字。

作用:就是修改請求封包的IP頭部中的source  IP Address為我們指定的IP位址。

proxy_ignore_client_abort

預設:proxy_ignore_client_abort off;

如果設定為on:

當用戶端到反向代理的連接配接斷開的時候,忽略這種情況,不斷開反向代理同上遊伺服器的連接配接。

會給上遊帶來很大的性能壓力。

如果設定為 off:

當用戶端和nginx斷開連接配接的時候,nginx和上遊伺服器也斷開連接配接。

預設為off。

proxy_send_timeout

預設:proxy_send_timeout  60s;

把請求發送給上遊伺服器,後請求的逾時時間。

接收上遊的響應

proxy_buffer_size

預設:proxy_buffer_size  4k|8k;

作用

限制了反向代理可以接收的上遊的最大header,如果上遊傳回的響應有cookie等非常大的資料,可能會導緻整個header超出了nginx處理的能力。

會報錯,在錯誤日志檔案中生成:upstream sent  too big header

proxy_buffering

預設:proxy_buffering  on;

如果設定為ON

那麼nginx接收上遊的服務發送來的響應body,會先緩存起來,然後再發送出去。

預設設定為ON,因為nginx和上遊伺服器都是在内網中,網速非常快。而nginx和用戶端直接網速要慢很多,如果發送一個很大的body的話,那麼會導緻nginx和上遊伺服器有長時間的連接配接。而上遊服務,比如Django,或者Tomcat的并發能力是非常弱的。

表明我們想要快速釋放nginx和上遊伺服器之間的連接配接。

proxy_buffers

文法:proxy_buffers  number  size;

預設:proxy_buffers 8  4k|8k;

作用:

上個指令緩存上遊的響應body的時候,要寫到磁盤,就需要進行IO。

試想,如果我們不把上遊的body放到磁盤中,而是放到緩存中可以嗎?

這就是這個指令的效果,預設配置設定8個4k大小的緩存,也就是32k,如果這個緩存能夠放下上遊的body,就放到緩存中;否則,還是會向磁盤中寫。

proxy_max_temp_file_size

預設:proxy_max_temp_file_size 1024m;

作用:

當把上遊響應body寫到磁盤的時候,限制這個磁盤檔案大小的最大值。

如果超出了門檻值,也會出錯。

proxy_temp_write_sze

預設:proxy_temp_write_sze  8k|16k;

作用:當把上遊的body寫入磁盤的時候,每一次寫磁盤,寫進去的機關,一次8k或者16k。

proxy_temp_path

預設:proxy_temp_path  proxy_temp;

作用:把上遊的body寫入磁盤時候,檔案的路徑。

proxy_busy_buffers_size

預設:proxy_busy_buffers_size  8k|16k;

作用:

及時轉發body。

當從上遊接收一個很大的response body的時候,會先把它寫到磁盤或者緩存,但是每寫好8k或者16k,就像用戶端發送一次。

proxy_read_timeout

預設:proxy_read_timeout 60s;

作用:TCP層的概念,兩次讀取之間的逾時時間是60秒,如果超過了這個事件,TCP連接配接應該就會斷開了。

proxy_limit_rate

預設:proxy_limit_rate 0;

作用

限制讀取上遊響應的速度。

設定為0,表示不限制。

proxy_store

如果設定為on

nginx接收上遊的響應body生成的臨時檔案,我們可以做持久化處理。

預設開啟。

proxy_store access

設定上邊持久化檔案的通路權限。

小例子:

nginx配置

server{

listen8080;

root/tmp;

location/a {

proxy_storeon;

proxy_store_accessuser:rw group:rw all:r;

}}

上遊服務配置

server{

listen8012;

location/ {

roothtml;

}

}

curl 192.168.188.60:8080/a.txt   這個指令上遊服務給我把a.txt檔案發送過來了,按道理說我也設定了持久化了,但是不知道為什麼,就是在nginx的機器上看不到把temp檔案持久化的結果。

處理上遊的響應

proxy_ignore_headers  field ...;

功能:上遊伺服器的某些響應頭可能會改變nginx的行為。這個指令可以讓指定的響應頭失效。

可以禁用功能的頭部:

proxy_hide_header  field;

功能:對于上遊響應中的某些頭部,設定預設不對用戶端轉發。

proxy_cookie_domain

proxy_cookie_path

上邊兩個指令都是nginx修改從上遊伺服器傳回的Set-Cookie頭部

proxy_redirect

nginx修改從上遊伺服器傳回的響應中的location頭部。

上遊出現失敗時的容錯方案

proxy_next_upstream

前提:上遊沒有向用戶端發送任何内容,哪怕一個位元組。

配置:

error

與上遊建立連接配接、讀取響應、發送請求,等等,任何一個環境出現了錯誤,都可以滿足條件,激活這個 指令。

timeout

命中 connetc_timeout 、 read_timeout等情景,會激活這個指令,重新選取一個upstream

invalid_header

收到的上遊的HTTP的header是不合法的。

http_

可以跟一個明确的響應code。

可以根據這樣的一個code去選擇另一個upstream

off

不開啟這個指令。

proxy_next_upstream_timeout

開始選用另一個upstream,直到選中某個upstream的逾時時間。

proxy_next_upstream_tries

如果設定為0,表示不再限制。

小例子一:

nginx的配置

upstreamnextups {

server127.0.0.1:8012 weight=1;

server127.0.0.1:8011 weight=1;

}

server{

listen8080;

location/ {

proxy_connect_timeout1s;

proxy_next_upstream off;

}

上遊伺服器的配置

server{

listen8011;

return200'8011 server response\n';

}

server{

listen8014;

return200'8012 server response\n';

}

上邊nginx中的upstream配置了兩個服務,分别在8011和8012端口;我上遊伺服器沒有開8012端口。

proxy_next_upstream 的值:

如果是off,執行curl 192.168.188.60:8080,可能會出錯,因為請求還是會被分發到8012端口上,nginx可能等一定時間,就會向不存在的端口上發送請求,就會傳回錯誤。

如果是error,當執行curl 192.168.188.60:8080時,不會傳回錯誤,請求都被分發到了8012端口上了。

小例子二、

nginx的配置

server{

listen8080;

location/httperr {

proxy_next_upstream http_500;

}

上遊服務的配置

server{

listen8011;

return200'8011 server response\n';

}

server{

listen8012;

return500'8012 system error\n';

}

執行curl 192.168.188.60:8080/httperr 指令,傳回根據proxy_next_upstream的值

如果為http_500

那麼所有的curl結果,都是8011 server response

如果為off,或者注釋掉這一行

那麼curl結果就是8011 server response 或者 8012 system error

proxy_intercept_errorson|off

預設為off。

作用:當上遊響應的響應碼>=300時,應該把響應傳回用戶端還是按照error_page指令處理。

總之來說,就是用error_page來攔截上遊失敗指令。

小例子:

nginx配置。

server{

listen8080;

error_page 500/a.txt;

location/intercept {

proxy_intercept_errorson;

}

}

上遊伺服器配置

server{

listen8012;

return500'8012 system error\n';

}

上邊設定了proxy_intercept_errors為on,那麼curl 192.168.188.60:8080/intercep,上遊伺服器會傳回500,這個500,被error_page攔截,進而執行了error_page的指令。

注意:error_page隻能攔截傳回值和他後邊code一樣的響應。