HTTP keep-alive和TCP keepalive的区别,你了解吗?
1、從文中找出我的IP
2、http請求中是客服端還是服務端主動關閉的tcp連接?
請閱讀到最后的彩蛋部分
HTTP和TCP都是老生常談的知識點,本文不進行鋪開贅述。我們可能在HTTP和TCP中都聽說“長連接”的說法,也聽過HTTP中有keep-alive,TCP中有keepalive。那么,HTTP和TCP的長連接有何區別?HTTP中的keep-alive和TCP中keepalive又有什么區別?
Tips:HTTP中是keep-alive,TCP中是keepalive,HTTP中是帶中劃線的。大小寫無所謂。
一、簡介
上面是我先前做TCP協議分享時整理的一張表格,從上面可以看出:不管是在OSI七層網絡模型還是在TCP/IP五層網絡模型中,TCP是傳輸層的一種協議,而HTTP是應用層的一種協議。
HTTP和TCP的理論和實現還是相當復雜的,下面只簡單介紹和本文主題相關的知識點。
1.1、TCP協議簡介
TCP協議也叫傳輸控制協議(TCP,Transmission Control Protocol)是一種面向連接的、可靠的、基于字節流的傳輸層通信協議。使用TCP的兩個程序(客戶端和服務端)在交換數據前,通過三次握手來建立TCP連接,建立連接后就可以進行基于字節流的雙工通訊,由TCP內部實現保證通訊的可靠性,完全通訊完成后,通過四次揮手斷開連接。
在客戶端和服務端間的網絡一切正常、且雙方都沒主動發起關閉連接的請求時,此TCP連接理論上可以永久保持。但是,網絡情況是及其復雜的,在雙方長時間未通訊時,如何得知對方還活著?如何得知這個TCP連接是健康且具有通訊能力的?
1.2、HTTP協議簡介
HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫。HTTP是萬維網的數據通信的基礎。HTTP是一個應用層協議,通常運行在TCP協議之上。它由請求和響應構成,是一個標準的客戶端服務器模型(C/S模型)。HTTP是一個無狀態的協議。
無狀態怎么解釋?HTTP協議永遠都是客戶端發起請求,服務器回送響應。每次連接只處理一個請求,當服務器返回本次請求的應答后便立即關閉連接,下次請求客戶端再重新建立連接。也就無法實現在客戶端沒有發起請求的時候,服務器主動將消息推送給客戶端。
HTTP協議運行在TCP協議之上,它無狀態會導致客戶端的每次請求都需要重新建立TCP連接,接受到服務端響應后,斷開TCP連接。對于每次建立、斷開TCP連接,還是有相當的性能損耗的。那么,如何才能盡可能的減少性能損耗呢?
二、TCP keepalive
2.1、簡介
正如上面提出的問題:在雙方長時間未通訊時,如何得知對方還活著?如何得知這個TCP連接是健康且具有通訊能力的?
TCP的保活機制就是用來解決此類問題,這個機制我們也可以稱作:keepalive。?;顧C制默認是關閉的,TCP連接的任何一方都可打開此功能。有三個主要配置參數用來控制?;罟δ?。
如果在一段時間(?;顣r間:tcp_keepalive_time)內此連接都不活躍,開啟保活功能的一端會向對端發送一個?;钐綔y報文。
- 若對端正常存活,且連接有效,對端必然能收到探測報文并進行響應。此時,發送端收到響應報文則證明TCP連接正常,重置?;顣r間計數器即可。
- 若由于網絡原因或其他原因導致,發送端無法正常收到保活探測報文的響應。那么在一定**探測時間間隔(tcp_keepalive_intvl)后,將繼續發送保活探測報文。直到收到對端的響應,或者達到配置的探測循環次數上限(tcp_keepalive_probes)**都沒有收到對端響應,這時對端會被認為不可達,TCP連接隨存在但已失效,需要將連接做中斷處理。
在探測過程中,對端主機會處于以下四種狀態之一:
2.2、實驗
這里,強烈推薦《TCP/IP詳解 卷1:協議》的第二版(這里一定是第二版), 第17章:TCP保活機制。這里建議17章都看,17.1和17.2小節就涵蓋了我上面介紹的內容。
17.2.1 小節中還通過實驗的方式詳細驗證了“對端主機會處于以下四種狀態”以及對于這四種狀態TCP都是如何去處理。
這本書中的實驗已經比較通俗易懂了,我暫且沒有親自動手去模擬實踐,后續時間充足,會親自動手進行實驗。
2.3、擴展
上面提到了三個參數?;顣r間:tcp_keepalive_time、探測時間間隔:tcp_keepalive_intvl、探測循環次數:tcp_keepalive_probes。
這三個參數,在linux上可以在/proc/sys/net/ipv4/路徑下找到,或者通過sysctl -a | grep keepalive命令查看當前內核運行參數
[root@vm01 ~]# cd /proc/sys/net/ipv4 [root@vm01 ipv4]# pwd /proc/sys/net/ipv4 [root@vm01 ipv4]# cat /proc/sys/net/ipv4/tcp_keepalive_time 7200 [root@vm01 ipv4]# cat /proc/sys/net/ipv4/tcp_keepalive_probes 9 [root@vm01 ipv4]# cat /proc/sys/net/ipv4/tcp_keepalive_intvl 75 [root@vm01 ipv4]# sysctl -a | grep keepalive net.ipv4.tcp_keepalive_time = 7200 net.ipv4.tcp_keepalive_probes = 9 net.ipv4.tcp_keepalive_intvl = 75- ?;顣r間(tcp_keepalive_time)默認:7200秒
- ?;顣r間間隔(tcp_keepalive_intvl)默認:75秒
- 探測循環次數(tcp_keepalive_probes)默認:9次
也就是默認情況下一條TCP連接在2小時(7200秒)都沒有報文交換后,會開始進行保活探測,若再經過9*75秒=11分鐘15秒的循環探測都未收到探測響應,即共計:2小時11分鐘15秒后會自動斷開TCP連接。
別走開,還有一個騷操作
相關視頻推薦
后臺開發第299講|大廠面試必問-如何實現UDP可靠性傳輸|1.C/C++程序員必問的TCP/UDP應用場景 2.UDP編程的各種坑 3.如何設計可靠UDP傳輸
需要C/C++ Linux服務器架構師學習資料加qun956314242獲取(資料包括C/C++,Linux,golang技術,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK,ffmpeg等),免費分享
Linux平臺下我們還可以借助man命令查看TCP協議的一些描述和參數定義。下面兩個命令的效果相同:
- 命令一:man tcp
- 命令二:man 7 tcp
7的含義是:man命令使用手冊共9章,TCP的幫助手冊位于第7章。不知道在第幾章也無所謂,使用man tcp也可,彈出的手冊左上角也有寫第幾章。(man ls等同于man 1 ls、man ip等同于man 8 ip,可以自己嘗試使用 )。
下面我們看下man tcp下的和我們本文有關的幾個點:
上面介紹的三個參數tcp_keepalive_time、tcp_keepalive_intvl、tcp_keepalive_probes都是系統級別的,針對整個系統生效。下面介紹針對單條Socket連接細粒度設置的三個選項參數:?;顣r間:TCP_KEEPIDLE、?;钐綔y時間間隔:TCP_KEEPINTVL、探測循環次數:TCP_KEEPCNT
在我們的Netty的框架中可以看到針對Socket選項的配置,如使用epoll的IO模型中EpollSocketChannelConfig類中的配置:
更多細節,等你挖掘。
三、HTTP keep-alive
3.1、簡介
HTTP協議簡介中提到http協議是一個運行在TCP協議之上的無狀態的應用層協議。它的特點是:客戶端的每一次請求都要和服務端創建TCP連接,服務器響應后,斷開TCP連接。下次客戶端再有請求,則重新建立連接。
在早期的http1.0中,默認就是上述介紹的這種“請求-應答”模式。這種方式頻繁的創建連接和銷毀連接無疑是有一定性能損耗的。
所以引入了keep-alive機制。http1.0默認是關閉的,通過http請求頭設置“connection: keep-alive”進行開啟;http1.1中默認開啟,通過http請求頭設置“connection: close”關閉。
keep-alive機制:若開啟后,在一次http請求中,服務器進行響應后,不再直接斷開TCP連接,而是將TCP連接維持一段時間。在這段時間內,如果同一客戶端再次向服務端發起http請求,便可以復用此TCP連接,向服務端發起請求,并重置timeout時間計數器,在接下來一段時間內還可以繼續復用。這樣無疑省略了反復創建和銷毀TCP連接的損耗。
3.2、實驗
下面用兩組實驗證明HTTP keep-alive的存在。
實驗工具:Wireshark
客戶端IP:*.*.3.52
服務端IP:*.*.17.254
3.2.1、實驗一:禁用keep-alive的http請求
從上圖請求列表區中,我們可以發現:
- 106、107、108三個請求是TCP建立連接三次握手的請求
- 109、110兩個請求分別是:http的請求報文和http的響應報文
- 111、112、120、121這四個請求是TCP斷開連接四次揮手的請求
(由于一臺機器上網絡請求較多,我加了篩選條件,僅顯示客戶端和服務端通信的網絡請求,所以請求的序號是不連續的)
從上圖中間的請求數據解析區,可以確定:此次http請求的請求頭中有“Connection: close”,即keep-alive是關閉的。
結論:禁用keep-alive的http請求時,會先建立TCP連接,然后發送報文、響應報文、最后斷開TCP連接。
3.2.2、實驗二:啟用keep-alive的http請求
這次實驗請求較多,一張圖放不下,兩張圖是連續的,圖1的第二塊綠色區域和圖2的第一塊綠色區域是重疊的(注意看第一列的No.編號)
先說下我的操作:
我們根據圖中抓包,分析下網絡請求:
- 197、198、199請求:三次握手建立TCP建立連接
- 200、203請求:http的請求報文和http的響應報文
- 212請求:可以通過Protocol列看到它是一條TCP報文。我的理解是:在keep-alive這種機制下,客戶端收到服務端響應報文后,需要告知服務端“已收到”。由于要復用TCP連接,所以會多一層保障機制,類似TCP的握手和揮手
- 459-1965請求(圖1中的第一塊黑色區域中):6秒內(第二列代表Time),每隔1秒,發生一對TCP請求的來回,用來維護TCP連接的可用性。保證和等待該TCP連接被復用
- 1743、1744、1745、1755請求:其中的1743和1745是我第二次發起http請求的請求報文和響應報文。1744請求是:客戶端發起請求時,服務端先回復客戶端“已收到,馬上處理”。緊接著1745將結果響應給客戶端。1755則是客戶端收到響應后,回復服務端“已收到響應,多謝”。
- 2028-3903請求:10秒內,每隔1秒,發生一對TCP請求的來回,用來維護TCP連接的可用性。保證和等待該TCP連接被復用
- 4127-4131請求:10秒內我沒再發起http請求,四次揮手斷開TCP連接。長時間沒被復用,也沒必要一直維持下去,浪費資源,還可能造成網絡擁堵。
注意:10秒無請求,TCP連接在斷開,10秒也不是默認的,只是環境的配置。是Httpd守護進程,提供的keep-alive timeout時間設置參數。比如nginx的keepalive_timeout,和Apache的KeepAliveTimeout。
3.3、擴展
其實對于HTTP keep-alive機制可以總結為上圖所示。
啟用HTTP keep-Alive的優缺點:
優點:keep-alive機制避免了頻繁建立和銷毀連接的開銷。 同時,減少服務端TIME_WAIT狀態的TCP連接的數量(因為由服務端進程主動關閉連接)
缺點:若keep-alive timeout設置的時間較長,長時間的TCP連接維持,會一定程度的浪費系統資源。
總體而言,HTTP keep-Alive的機制還是利大于弊的,只要合理使用、配置合理的timeout參數。
四、總結
回到文章開頭提出的問題:HTTP和TCP的長連接有何區別?HTTP中的keep-alive和TCP中keepalive又有什么區別?
1、TCP連接往往就是我們廣義理解上的長連接,因為它具備雙端連續收發報文的能力;開啟了keep-alive的HTTP連接,也是一種長連接,但是它由于協議本身的限制,服務端無法主動發起應用報文。
2、TCP中的keepalive是用來保鮮、?;畹?#xff1b;HTTP中的keep-alive機制主要為了讓支撐它的TCP連接活的的更久,所以通常又叫做:HTTP persistent connection(持久連接) 和 HTTP connection reuse(連接重用)。
五、彩蛋
彩蛋一
你能從文中找出我在HTTP keep-alive實驗中客戶端和服務端的完整IP嗎?
如能找出,說明對網絡協議的了解已爐火純青。
彩蛋二
在HTTP請求中,到底是「服務端」還是「客戶端」主動關閉連接呢?
看到過很多文章,有人說服務端、有人說客戶端、有人說分情況(keep-alive的開啟與否)既可能是客戶端也可能是服務端。你信誰?最后翻來覆去發現各個網站的各種文章基本類似,只有觀點,沒有論據。
HTTP keep-alive章節的實驗結果:無論開啟keep-alive與否,最終由服務端主動斷開TCP連接。
但是我給出問題的答案是:通常由服務端主動關閉連接。沒有寫“肯定由服務端主動關閉連接”的原因是,我沒遇到客戶端主動關閉連接的場景,并不代表沒有。網絡和協議博大精深,等待我們繼續去探索。
彩蛋三
Wireshark是一款功能強大的網絡封包分析可視化軟件?!禩CP/IP詳解 卷1:協議》第二版相比第一版,書中的抓包工具也將tcpdump改為****Wireshark。****
個人觀點:《TCP/IP詳解 卷1:協議》第一版和第二版結合起來看效果更好。第一版的TCP阻塞控制將的更通俗易懂,第二版的TCP?;顧C制講的更清晰。
總結
以上是生活随笔為你收集整理的HTTP keep-alive和TCP keepalive的区别,你了解吗?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows cmd命令行操作技巧
- 下一篇: 生成1000个不同的随机数