驗證Nginx的長連接(keepalive)配置

寫在前面

最近都在折騰 Nginx 服務器的學習和測試,前幾天稍微溫習了一下計算機網絡方面的知識(一方面是興趣,一方面是這次學習過程中因爲這些計算機基礎遺忘,有很多細節問題讓人很懵逼),也在 Linux 上試了一下 tcpdump 命令,通過抓包來驗證自己之前的各種猜想(因爲不懂所以瞎猜),分析數據包依舊是用的 Wireshark

之前一直以爲只要使用 Http1.1 協議就可以複用連接,節省反覆握手揮手的時間消耗,但抓包後才發現,"簡簡單單"的長連接使用,還真是涉及了 Nginx 、 JMeter 、 Tomcat 裏的很多配置啊

  • JMeter 雖然在 Http 請求的配置中默認勾選了使用 KeepAlive,但是實際使用中並沒有生效
  • Nginx 涉及到與客戶端的配置 keepalive_timeoutkeepalive_requests,與後端服務器的配置 keepalive(1.15.3之後,upstream 模塊也新增了 keepalive_timeoutkeepalive_requests,本篇暫不涉及)
  • Tomcat 默認也有一個 keepAliveTimeout 配置

知道了這些相關配置後,一方面想實戰下 tcpdump 和 Wireshark 的使用,一方面也想用數據驗證下 Nginx 的這三個配置,所以就有了接下來的內容


環境說明

  • Nginx 1.14.0
  • Linux 2.6.32
  • JMeter 5.0
  • Wireshark 2.6.4
  • JMeter 所在主機 IP 172.16.40.199
  • Tomcat 所在主機 IP 172.16.40.201
  • Nginx 所在主機 IP 172.16.40.224

0. 和客戶端的長連接超時時間

指令說明

語法: keepalive_timeout timeout [header_timeout];

默認值: keepalive_timeout 75s;

上下文: http, server, location

第一個參數設置客戶端的長連接在服務器端保持的最長時間(在此時間客戶端未發起新請求,則長連接關閉)。 第二個參數爲可選項,設置“Keep-Alive: timeout=time”響應頭的值。 可以爲這兩個參數設置不同的值。

“Keep-Alive: timeout=time”響應頭可以被 Mozilla 和 Konqueror 瀏覽器識別和處理。 MSIE 瀏覽器在大約60秒後會關閉長連接。

測試計劃

keepalive_timeout = 1

客戶端持續發起 http 請求,且不主動關閉連接,觀察連接的釋放時間

測試過程

用 JMeter 測試時發現不能維持長連接,在請求結束時都由 JMeter 自己發起連接關閉,按官方 wiki 說明修改 jmeter.properties 和 user.properties 中的相關配置,測試一下沒看到生效,最後還是用 Apache 的 HttpClient 自己寫了點代碼才做了這個測試

代碼中循環啓動多個線程,每個線程啓動後不間斷髮起10次請求,且執行後沒有主動關閉 client 和 response

測試結果

驗證keepalive_timeout.png

結果說明

如上所述,測試客戶端發起數次請求,請求結束時沒有關閉連接(這裏有個小問題,連接沒有複用,可能是需要配置 client 連接池,我暫時沒去折騰)

1秒(超時)後,由 Nginx 服務器發起關閉請求


1. 和客戶端的長連接請求次數

指令說明

語法: keepalive_requests number

默認值: keepalive_requests 100

上下文: http, server, location

這個指令出現在版本 0.8.0

設置通過一個長連接可以處理的最大請求數。 請求數超過此值,長連接將關閉。

測試計劃

keepalive_requests = 5

使用 curl 命令,發送8次(多於 keepalive_requests 個數的)請求,觀察請求5次後連接是否斷開

測試過程

最初使用 for 循環執行 curl 命令,發現命令執行完就立刻釋放了連接,在網上查了下,可以在一個命令裏訪問多次,例如:

curl http://172.16.40.224:6066/NginxTest/hi http://172.16.40.224:6066/NginxTest/hi http://172.16.40.224:6066/NginxTest/hi http://172.16.40.224:6066/NginxTest/hi http://172.16.40.224:6066/NginxTest/hi http://172.16.40.224:6066/NginxTest/hi http://172.16.40.224:6066/NginxTest/hi http://172.16.40.224:6066/NginxTest/hi

這樣的話,就會等8次請求都結束,才關閉連接

測試結果

驗證keepalive_requests.png

結果說明

可以看出第一個 TCP 連接共發起了5次 Http 請求,緊接着由 Nginx 發起了關閉

第二個 TCP 連接發起了剩餘的3次 Http 請求,緊接着由客戶端發起了關閉


2. 和後端服務器的長連接個數

指令說明

語法: keepalive connections

默認值: —

上下文: upstream

這個指令出現在版本 1.1.4

connections 參數設置每個 worker 進程與後端服務器保持連接的最大數量。這些保持的連接會被放入緩存。 如果連接數大於這個值時,最久未使用的連接會被關閉。

測試計劃

keepalive = 10

用 JMeter 啓動多於 keepalive 個數的測試進程,觀察測試結束後的連接關閉情況

測試過程

使用 JMeter 的 GUI 客戶端編輯一個測試腳本開啓50個進程,循環測試120秒

測試結果

驗證keepalive.png

結果說明

可以看出截至118秒(JMeter 逐漸停止發起測試請求),都在逐個關閉 TCP 連接,截圖部分大都是後端服務器響應的 FIN 包,稍微往前一點能看到都是由 Nginx 主動發起的關閉請求

從138秒開始(後端 Tomcat 服務器的長連接超時時間默認20秒),剩餘的10個長連接被後端服務器發起了關閉請求


最後

測試過程涉及到的 tcpdump 命令是

sudo tcpdump -i eth0 host 172.16.40.xxx -w dumplog.pcap

-i 指定網卡
host 指定抓取和哪個 IP 之間的數據包
-w 將抓取結果保存到 pcap 文件,用於使用 Wireshark 查看

通過上面的三個測試,理解和驗證了 Nginx 分別在面向客戶端和麪向後端服務器時的長連接使用情況


打個廣告

文章首發於個人博客《驗證Nginx的長連接(keepalive)配置》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章