最近都在折騰 Nginx 服務器的學習和測試,前幾天稍微溫習了一下計算機網絡方面的知識(一方面是興趣,一方面是此次學習過程當中由於這些計算機基礎遺忘,有不少細節問題讓人很懵逼),也在 Linux 上試了一下 tcpdump
命令,經過抓包來驗證本身以前的各類猜測(由於不懂因此瞎猜),分析數據包依舊是用的 Wiresharkgit
以前一直覺得只要使用 Http1.1 協議就能夠複用鏈接,節省反覆握手揮手的時間消耗,但抓包後才發現,"簡簡單單"的長鏈接使用,還真是涉及了 Nginx 、 JMeter 、 Tomcat 裏的不少配置啊github
keepalive_timeout
和 keepalive_requests
,與後端服務器的配置 keepalive
(1.15.3以後,upstream 模塊也新增了 keepalive_timeout
和 keepalive_requests
,本篇暫不涉及)keepAliveTimeout
配置知道了這些相關配置後,一方面想實戰下 tcpdump
和 Wireshark 的使用,一方面也想用數據驗證下 Nginx 的這三個配置,因此就有了接下來的內容web
語法: 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
如上所述,測試客戶端發起數次請求,請求結束時沒有關閉鏈接(這裏有個小問題,鏈接沒有複用,多是須要配置 client 鏈接池,我暫時沒去折騰)
1秒(超時)後,由 Nginx 服務器發起關閉請求
語法: 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次請求都結束,才關閉鏈接
能夠看出第一個 TCP 鏈接共發起了5次 Http 請求,緊接着由 Nginx 發起了關閉
第二個 TCP 鏈接發起了剩餘的3次 Http 請求,緊接着由客戶端發起了關閉
語法: keepalive connections默認值: —
上下文: upstream
這個指令出如今版本 1.1.4
connections 參數設置每一個 worker 進程與後端服務器保持鏈接的最大數量。這些保持的鏈接會被放入緩存。 若是鏈接數大於這個值時,最久未使用的鏈接會被關閉。
keepalive = 10
用 JMeter 啓動多於 keepalive 個數的測試進程,觀察測試結束後的鏈接關閉狀況
使用 JMeter 的 GUI 客戶端編輯一個測試腳本開啓50個進程,循環測試120秒
能夠看出截至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)配置》