在基礎架構部沉浸了半年,有一些認知刷新想和童靴們交代一下, 不一定全面,僅代表此時的認知, 也歡迎筒靴們提出看法。
本文聊一聊口嗨用語:“長連接、短連接”, 文章會按照下面的思維導圖來講述:
重點圍繞這兩個難點/思維誤區來整理知識體系。
- 長連接 vs 短連接
- Http1.1持久連接 vs WebSocket長連接
長連接 vs 短連接
長連接
是指一個連接上連續發送多個數據包。
短連接
是指雙方要數據交互時,建立一個連接,數據發送完畢,則斷開連接,即每次連接只完成一個單元的業務傳輸,有需要再建立新連接傳輸數據。
實際上長短連接都是針對TCP連接而言的,強調的是應用層對下層TCP連接的使用姿勢,采用哪種連接由應用根據自身情況決定。
長連接
多用於操作頻繁、點對點的通信,而且連接數不能太多的情況。每次TCP連接都需要三次握手,這需要時間,如果每個操作都是短連接,再操作的話那么處理速度會降低很多,所以每次操作完后都不斷開,下次處理時直接發送數據包就OK了,不用建立TCP連接。例如:數據庫的連接用長連接,如果用短連接頻繁的通信會造成socket錯誤,而且頻繁的socket 創建也是對資源的浪費。
而常規web網站一般都是短連接,這是由web站點的特征決定,web站點的客戶端數量大、訪問時間/頻次不固定,采用短連接能節省服務器資源;如果客戶端都維持長連接,可想而知,會占用多大的服務器資源, 所以並發量大,但每個用戶無需頻繁操作的時候使用短連接較好。
Http1.1持久連接
早期HTTP1.0是純粹的TCP短連接的應用,每個連接完成一次Http請求/響應模型,這種方式頻繁的創建/銷毀連接無疑是有一定性能損耗的。
目前普遍應用的HTTP1.1的Keep-alive官方術語上叫持久連接(英語:HTTP persistent connection,也稱作HTTP keep-alive或HTTP connection reuse),國內口嗨稱為“HTTP長連接”。
HTTP1.1keep-alive
,我認為是應用層HTTP協議對於TCP連接的折中使用,是在應用層對下層TCP連接的協商使用,這種協商以客戶端/服務端的Connection:Keep-alive
標頭體現。
-
Http1.0 頻繁創建/銷毀連接確實給通信雙方帶來了不必要的性能損耗 #不必要#
-
直接使用典型的長連接又會給服務端帶來極大的壓力 #不允許#
故HTTP1.1的keep-alive
一方面允許多個HTTP請求復用一個TCP連接, 另一方面又將這種復用時效交由客戶端/服務端在應用層協商:應用層每次請求/響應均攜帶Connection標頭滑動續約來體現。
HTTP 1.1 Keep-Alive的實質是應用層滑動續約復用TCP連接?
根據一些官方文檔,無論是客戶端、還是服務端,均有等待TCP連接活躍的超時時間,
- 客戶端IE默認的KeepAliveTimeout是1分鍾;
- 服務器IIS默認ConnectionTimeout時長2min
- 服務器ASP.NetCore Kestrel默認的KeepAliveTimeout=130s
- 服務器nginx默認的keepalive_timeout=60s
這里面明眼人一看,1.2.4針對TCP Connection復用的滑動超時時間是拍腦袋決定的,而第3點ASP.NET Core Kestrel作為.NETCore的寄宿服務器為什么是130s, 是不是有點意思。
我給你們找出來了, KestrelServerLimits.KeepAliveTimeout=130s
典型的長連接WebSocket
WebSocket是一種典型的長連接,通過第一個HTTP Request建立了TCP連接之后,之后數據交互都不需要發送HTTP Request了,但是不需要發送HTTP request就能交換數據顯然和原有的 HTTP 協議是有區別的,所以它需要對服務器和客戶端都進行升級才能實現,這個協商是在Websocket數據傳輸之前就已經完成。
- 握手: 通過第一個http請求中攜帶特定標頭,要求升級協議,服務器恢復101 ,確認升級協議
- 數據傳輸: 之后全 雙工工通信,不需要發送request, 發送消息, 消息由一個或多個幀組成,一個幀可以是二進制、文本、控制幀(0x8 Close,0x9 Ping,0xA Pong)
WebSocket也有Keepalive機制,WebSocket的Keep-alive的作用是在復雜的網絡環境中探測連接的對端是否還存活。
旁白
- 長短連接都是針對TCP連接而言,強調的是應用層對於TCP連接的使用姿勢。
- HTTP1.1 Keep-alive是對TCP連接的折中使用,既不是短連接,也不能稱為典型的長連接。
- HTTP1.1 Keep-alive官方稱持久連接,我的觀點是HTTP1.1 Keep-Alive 是在應用層對TCP連接進行滑動續約復用。
特定於連接的標頭字段(例如 Connection)不得與 HTTP/2 一起使用
- 典型的長連接WebSocket在數據傳輸之前就完成了長連接確認, 之后全雙工通信,發送消息(由幀組成)。