我們一起聊聊 Nginx 后端長連接
nginx 后端長連接
Nginx 后端長連接的優(yōu)點(diǎn)包括:
- 減少連接建立和關(guān)閉的消耗和延遲:在一個(gè) TCP 連接上可以傳送多個(gè) HTTP 請(qǐng)求和響應(yīng),避免了頻繁建立和關(guān)閉連接的開銷,提高了性能。
- 降低服務(wù)器負(fù)載:特別是對(duì)于 QPS(每秒請(qǐng)求數(shù))較高或網(wǎng)絡(luò)環(huán)境不穩(wěn)定的場(chǎng)景,能夠有效減少服務(wù)器處理連接創(chuàng)建和關(guān)閉的壓力。
- 提升資源利用率:可以更有效地利用系統(tǒng)資源,避免連接頻繁創(chuàng)建和釋放導(dǎo)致的資源浪費(fèi)。
然而,Nginx 后端長連接也存在一些缺點(diǎn):
- 內(nèi)存使用問題:如果設(shè)置的長連接最大請(qǐng)求數(shù)過高,可能會(huì)導(dǎo)致過多的內(nèi)存使用。
- 連接管理復(fù)雜:需要合理配置相關(guān)參數(shù),如 keepalive 空閑連接數(shù)量,以適應(yīng)不同的請(qǐng)求負(fù)載和響應(yīng)情況,否則可能會(huì)出現(xiàn)連接數(shù)量的震蕩,在某些情況下仍然需要進(jìn)行連接的創(chuàng)建和釋放。
在 Nginx 中,涉及長連接的主要配置指令涵蓋以下幾個(gè)方面:
- keepalive_timeout:此指令用于設(shè)定 keep-alive 客戶端連接在服務(wù)器端維持開啟的超時(shí)值。例如,keepalive_timeout 120s 這一設(shè)置表明將超時(shí)值設(shè)定為 120 秒。
- keepalive_requests:該指令規(guī)定了一個(gè) keep-alive 連接能夠服務(wù)的請(qǐng)求的最大數(shù)量。舉例來說,keepalive_requests 1000 意味著將最大請(qǐng)求數(shù)量設(shè)定為 1000。
- proxy_http_version 1.1:需在 location 塊中進(jìn)行配置,旨在確保采用 HTTP 1.1 協(xié)議,因?yàn)殚L連接的支持始于 HTTP 1.1 版本。
- proxy_set_header connection "":用于清除來自客戶端請(qǐng)求中的 connection 頭部信息。
完成 Nginx 長連接的配置后,可通過查看 Nginx 的訪問日志和錯(cuò)誤日志來獲取與長連接有關(guān)的信息。
訪問日志一般會(huì)記錄客戶端的請(qǐng)求詳情,涵蓋請(qǐng)求的 URL、客戶端 IP 以及響應(yīng)狀態(tài)碼等。雖然它不會(huì)直接呈現(xiàn)長連接的相關(guān)信息,然而,通過觀察客戶端與 Nginx 之間的交互狀況,能夠推斷長連接的使用情況。
錯(cuò)誤日志則有可能會(huì)記錄長連接處理期間出現(xiàn)的問題,例如連接超時(shí)、連接被重置等錯(cuò)誤。
若要針對(duì)日志中的長連接相關(guān)問題展開具體分析,或許需要留意以下幾個(gè)要點(diǎn):
- 查看是否存在頻繁的連接建立與關(guān)閉的記錄,這種情況可能暗示長連接未能正常運(yùn)作。
- 留意錯(cuò)誤日志中是否出現(xiàn)類似于 readv() failed (104: Connection reset by peer) 等與連接相關(guān)的錯(cuò)誤提示信息。
倘若在長連接的使用過程中遭遇問題,可以依據(jù)日志中的具體錯(cuò)誤提示展開進(jìn)一步的排查與解決。比如,調(diào)整 keepalive_timeout 和 keepalive_requests 的值,或者對(duì)網(wǎng)絡(luò)環(huán)境、后端服務(wù)器的配置等進(jìn)行檢查。此外,務(wù)必保證 Nginx 自身以及后端服務(wù)器均能夠正常支持長連接,并且網(wǎng)絡(luò)的穩(wěn)定也是確保長連接正常工作的關(guān)鍵因素。
要是問題依舊存在,可以提供更為詳盡的錯(cuò)誤日志信息,以便進(jìn)行更精準(zhǔn)的分析和診斷。
以下為相關(guān)的 Nginx 配置示例:
http {
# 與客戶端的長連接設(shè)置
keepalive_timeout 120s; # 設(shè)置客戶端連接在服務(wù)器端保持開啟的超時(shí)值為 120 秒
keepalive_requests 10000; # 設(shè)置一個(gè) keep-alive 連接上可以服務(wù)的請(qǐng)求的最大數(shù)量為 10000
# 與后端服務(wù)器的長連接設(shè)置
upstream backend {
server 192.168.0.1:8080 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.0.2:8080 weight=1 max_fails=2 fail_timeout=30s;
keepalive 300; # 設(shè)置每個(gè) worker 進(jìn)程與 upstream 服務(wù)器建立的最多空閑 keep-alive 連接數(shù)量為 300
}
server {
listen 8080 default_server;
server_name "";
location / {
proxy_pass http://backend;
proxy_set_header host $host;
proxy_set_header x-forwarded-for $remote_addr;
proxy_set_header x-real-ip $remote_addr;
add_header cache-control no-store;
add_header pragma no-cache;
proxy_http_version 1.1; # 設(shè)置與后端服務(wù)器通信采用的 HTTP 版本為 1.1
proxy_set_header connection ""; # 清理來自客戶端請(qǐng)求中的 'connection' header
}
}
}
例如,對(duì)于一個(gè)響應(yīng)時(shí)間為 100 毫秒,要求性能達(dá)到 10000 QPS 的 HTTP 服務(wù),可能需要在 Nginx 與上游服務(wù)器之間建立大概 1000 條 HTTP 請(qǐng)求(1000 / 0.1s = 10000)。
假設(shè) keepalive 的值設(shè)置為 10,在請(qǐng)求和應(yīng)答都均勻平穩(wěn)的情況下,每 0.1 秒有 1000 個(gè)請(qǐng)求收到并釋放,連接池中沒有空閑連接,無需建立新連接。
但如果應(yīng)答平穩(wěn)而請(qǐng)求不平穩(wěn),如第 0.3 秒只有 500 個(gè)請(qǐng)求收到,Nginx 檢測(cè)到連接池中有 500 個(gè)空閑連接,就可能關(guān)閉(500 - 10)個(gè)連接;而在第 0.4 秒收到 1500 個(gè)請(qǐng)求時(shí),由于池里只有(500 + 10)個(gè)連接,Nginx 不得不重新建立(1500 - 510)個(gè)連接。若不關(guān)閉那 490 個(gè)連接,則只需重新建立 500 個(gè)連接。
同樣,在請(qǐng)求平穩(wěn)但應(yīng)答不平穩(wěn)時(shí),也可能出現(xiàn)連接數(shù)量的反復(fù)震蕩。
總之,通過合理配置 Nginx 后端長連接,可以充分發(fā)揮其優(yōu)勢(shì),提高系統(tǒng)的性能和資源利用率,但需根據(jù)實(shí)際情況仔細(xì)調(diào)整相關(guān)參數(shù),以避免潛在的問題。