HTTP的長連接和短連接本質上是TCP長連接和短連接。
短連接
短連接,顧名思義,與長連接的區別就是,客戶端收到服務端的響應后,立刻發送FIN消息,主動釋放連接。也有服務端主動斷連的情況,凡是在一次消息交互(發請求-收響應)之后立刻斷開連接的情況都稱為短連接。
長連接/http keep-alive
也叫持久連接,即一個TCP連接服務多次請求,在TCP層握手成功后,不立即斷開連接,并在此連接的基礎上進行多次消息(包括心跳)交互,直至連接的任意一方(客戶端OR服務端)主動斷開連接,此過程稱為一次完整的長連接。
在HTTP/1.0中得到了初步的支持,客戶端在請求header中攜帶Connection:Keep-Alive,即是在向服務端請求持久連接。如果服務端接受持久連接,則會在響應header中同樣攜帶Connection: Keep-Alive,這樣客戶端便會繼續使用同一個TCP連接發送接下來的若干請求。(Keep-Alive的默認參數是[timout=5, max=100],即一個TCP連接可以服務至多5秒內的100次請求)
HTTP/1.1開始,即使請求header中沒有攜帶Connection: Keep-Alive,傳輸也會默認以持久連接的方式進行,只有加入"Connection: close "后,才關閉。
http keepalive是客戶端瀏覽器與服務端httpd守護進程協作的結果。
TCP中的KeepAlive
??TCP協議的實現中,提供了KeepAlive報文,用來探測連接的對端是否存活。在應用交互的過程中,可能存在以下幾種情況:
客戶端或服務器意外斷電,死機,崩潰,重啟;
中間網絡已經中斷,而客戶端與服務器并不知道;
利用保活探測功能,可以探知這種對端的意外情況,從而保證在意外發生時,可以釋放半打開的TCP連接。TCP保活報文交互過程如下:
有了TCP提供了KeepAlive機制, 為什么還需要應用層的心跳保活:
(1) Keep Alive機制開啟后,TCP層將在定時時間到后發送相應的KeepAlive探針以確定連接可用性。默認時間為7200s(兩小時),失敗后重試10次,每次超時時間75s。顯然默認值無法滿足移動網絡下的需求;
(2) 即便修改了(1)中的默認值,也不能很好的滿足業務需求。TCP的KeepAlive用于檢測連接的死活而不能檢測通訊雙方的存活狀態。比如某臺服務器因為某些原因導致負載超高,無法響應任何業務請求,但是使用TCP探針則仍舊能夠確定連接狀態,這就是典型的連接活著但業務提供方已死的狀態,對客戶端而言,這時的最好選擇就是斷線后重新連接其他服務器,而不是一直認為當前服務器是可用狀態,一直向當前服務器發送些必然會失敗的請求。
(3) socks代理會讓Keep Alive失效。socks協議只管轉發TCP層具體的數據包,而不會轉發TCP協議內的實現細節的包。所以,一個應用如果使用了socks代理,那么TCP的KeepAlive機制就失效了。
(4) 部分復雜情況下Keep Alive會失效,如路由器掛掉,網線直接被拔除等;
因此,KeepAlive并不適用于檢測雙方存活的場景,這種場景還得依賴于應用層的心跳。應用層心跳也具備著更大的靈活性,可以控制檢測時機,間隔和處理流程,甚至可以在心跳包上附帶額外信息。
影響心跳頻率的關鍵因素
應用層心跳是檢測連接有效性以及判斷雙方是否存活的有效方式。但是心跳過于頻繁會帶來耗電和耗流量的弊病,心跳頻率過低則會影響連接檢測的實時性。業內關于心跳時間的設置和優化,主要基于如下幾個因素:
- 1.NAT超時–大部分移動無線網絡運營商在鏈路一段時間沒有數據通訊時,會淘汰 NAT表中的對應項,造成鏈路中斷;
- 2.DHCP租期–DHCP租期到了需要主動續約,否則會繼續使用過期IP導致長連接偶然的斷連;
- 3.網絡狀態變化–手機網絡和WIFI網絡切換、網絡斷開和連上等情況有網絡狀態的變化,也會使長連接變為無效連接;
理想的情況下,客戶端應當以略小于NAT超時時間的間隔來發送心跳包。根據微信團隊測試的一些數據,一些常用網絡的NAT超時時間如下表所示:
Tcp keepAlive 和Http中Keep-Alive的關系
HTTP協議的Keep-Alive意圖在于連接復用,同一個連接上串行方式傳遞請求-響應數據
TCP的KeepAlive機制意圖在于保活、心跳,檢測連接錯誤
如何快速區分當前連接使用的是長連接還是短連接
1、凡是在一次完整的消息交互(發請求-收響應)之后,立刻斷開連接(有一方發送FIN消息)的情況都稱為短連接;
2、長連接的一個明顯特征是會有心跳消息(也有沒有心跳的情況),且一般心跳間隔都在30S或者1MIN左右,用wireshark抓包可以看到有規律的心跳消息交互(可能會存在毫秒級別的誤差)。
什么時候用長連接,短連接?
1、需要頻繁交互的場景使用長連接,如即時通信工具(微信/QQ,QQ也有UDP),相反則使用短連接,比如普通的web網站,只有當瀏覽器發起請求時才會建立連接,服務器返回相應后,連接立即斷開。
2、維持長連接會有一定的系統開銷,用戶量少不容易看出系統瓶頸,一旦用戶量上去了,就很有可能把服務器資源(內存/CPU/網卡)耗盡,所以使用需謹慎。
keep-alive與TIME_WAIT
使用http keep-alvie,可以減少服務端TIME_WAIT數量(因為由服務端httpd守護進程主動關閉連接)。道理很簡單,相較而言,啟用keep-alive,建立的tcp連接更少了,自然要被關閉的tcp連接也相應更少了。
短連接和長鏈接 圖:
https://blog.csdn.net/hengyunabc/article/details/44310193
http://wingjay.com/2018/12/05/android-arch-long-link/
https://www.levicc.com/2018/06/30/yi-dong-duan-wang-luo-you-hua/
能被我參考的都很優秀,哈哈