關於 Nginx upstream keepalive 的說明


 

模塊是 HttpUpstreamModule,配置的一個例子:

[shell]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 "";
        …
    }
}[/shell]

 

有幾點要說明:

1. 默認情況下 Nginx 訪問后端都是用的短連接(HTTP1.0),一個請求來了,Nginx 新開一個端口和后端建立連接,請求結束連接回收。如果像上面的配置一樣設置了長連接,Nginx 會接受客戶端的請求,處理完成之后 Nginx 會「繼續保持和后端的長連接」,如果並發請求超過了 keepalive 指定的最大連接數,Nginx 會啟動新的連接 來轉發請求,新連接在請求完畢后關閉,而且新建立的連接是長連接,這可能會造成額外的問題,最后再說。

2. keepalive 指定的 數值 是 Nginx 每個 worker  連接后端的最大長連接數,而不是整個 Nginx 的。 而且這里的后端指的是「所有的后端」,而不是每一個后端(已驗證)。

3. 在官網上  可以看到 還有一個 single 參數,說實話我沒懂什么意思,但是它已經被廢棄了,看這里

4. HttpUpstreamModule 模塊里面還有一共指令:least_conn,解釋如下:

Specifies that a group should use a load balancing method where a request is passed to the server with the least number of active connections, taking into account weights of servers. If there are several such servers, they are tried in turn using a weighted round-robin balancing method.

翻譯:

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

使用這個指令的時候后端服務器的連接數好像會變的非常少,很奇怪,我還沒親自測過,待確認。

 

最后再說一下第 1 點,先說一個現象,我發現當 keepalive 設置小的時候,比如1,那么並發請求上去之后 Nginx 會出現大量的 TIME_WAIT,而如果把 keepalive 關掉(proxy_http_version 1.1 和 proxy_set_header Connection “” 指令也去掉),那么 TIME_WAIT 就會出現在后端服務器了,后端用的是 tornado,相信 jetty 和 tomcat 也是一樣。

這個現象是怎么產生的呢,做一個測試。

命令:ab -n 100 -c 5 http://pxe1.hy01/

pxe1.hy01 (Nginx,上面配置了長連接,ip: 10.0.31.84) ,它會轉到 pxe0.hy01 的 8888 端口(tornado,ip: 10.0.11.12)

測試的時候在 pxe1.hy01 執行抓包命令:

# tcpdump -i em2 -A host 10.0.11.12 -n

看到:

00:22:53.252039 IP 10.0.31.84.53915 > 10.0.11.12.ddi-tcp-1: Flags [P.], seq 81:161, ack 275, win 123, length 80
@.@.].
..T
…..”…p%8|..P..{>…GET / HTTP/1.1
Host: http_backend
User-Agent: ApacheBench/2.3
Accept: */*

但是如果把 pxe1.hy01 的長連接設置都去掉的話,抓包如下:

00:23:58.111974 IP 10.0.31.84.54051 > 10.0.11.12.ddi-tcp-1: Flags [P.], seq 1:100, ack 1, win 115, length 99
E…..@.@.Z=
..T
….#”…O…SUP..s>…GET / HTTP/1.0
Host: http_backend
Connection: close
User-Agent: ApacheBench/2.3
Accept: */*

那么上面出現的現象就好解釋了,是這樣:

Nginx 和后端的長連接不夠用時 Nginx 會新建連接來處理新的請求,而我們的配置已經配置死了 HTTP1.1,建立連接后,后端認為是「長連接」而不會主動關閉連接(一般有個空閑超時),關閉連接由 Nginx 來做了,所以 Nginx 會出現大量的 TIME_WAIT。

而默認情況下,Nginx 用 HTTP1.0 請求后端,后端處理完成后就主動關閉連接,所以 TIME_WAIT 在后端。

那么現在有新的問題了,如果開啟了長連接,而長連接又大量不夠用,此時 Nginx 存在的 TIME_WAIT 可能會大量占用端口,導致端口用盡,如果用盡,后果很嚴重。

所以,「慎用 Nginx 的 長連接」。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM