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

寫在前面

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

以前一直覺得只要使用 Http1.1 協議就能夠複用鏈接,節省反覆握手揮手的時間消耗,但抓包後才發現,"簡簡單單"的長鏈接使用,還真是涉及了 Nginx 、 JMeter 、 Tomcat 裏的不少配置啊github

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

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


環境說明

  • 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;apache

上下文: 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 本身寫了點代碼才作了這個測試curl

代碼中循環啓動多個線程,每一個線程啓動後不間斷髮起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)配置》

相關文章
相關標籤/搜索