轉自: https://blog.csdn.net/luzhensmart/article/details/87186401
1.以前的誤解
很久之前就聽說過長連接的說法,而且還知道HTTP1.0協議不支持長連接,從HTTP1.1協議以后,連接默認都是長連接。但終究覺得對於長連接一直懵懵懂懂的,有種抓不到關鍵點的感覺。
今天通過一番研究,終於明白了這其中的奧秘。而之前,也看過長連接相關的內容,但一直都是雲里霧里的。這次之所以能在這么短的時間里搞清楚,和自己技術的沉淀密不可分。因此,這里借着這個機會,再次強調一下,千萬不要試圖去研究你研究了很久都整不明白的東西,或許是你的層次不到,也或許是你從未在實際的應用場景接觸過,這種情況下你去研究,只會事倍功半,徒勞一番罷了。
回到正題,既然說是誤解,那么的誤解到底是什么?
那就是一直認為,HTTP連接分為長連接和短連接,而我們現在常用的都是HTTP1.1,因此我們用的都是長連接。
這句話其實只對了一半,我們現如今的HTTP協議,大部分都是1.1的,因此我們平時用的基本上都是長連接。但是前半句是不對的,HTTP協議根本沒有長短連接這一說,也正因為誤解了這個,導致對於長連接一直不明不白,始終不得其要領,具體下面一段會說到。
網絡上很多文章都是誤人子弟,根本沒有說明白這個概念。這里要強調一下,HTTP協議是基於請求/響應模式的,因此只要服務端給了響應,本次HTTP連接就結束了,或者更准確的說,是本次HTTP請求就結束了,根本沒有長連接這一說。那么自然也就沒有短連接這一說了。
之所以網絡上說HTTP分為長連接和短連接,其實本質上是說的TCP連接。TCP連接是一個雙向的通道,它是可以保持一段時間不關閉的,因此TCP連接才有真正的長連接和短連接這一說。
其實知道了以后,會覺得這很好理解。HTTP協議說到底是應用層的協議,而TCP才是真正的傳輸層協議,只有負責傳輸的這一層才需要建立連接。
一個形象的例子就是,拿你在網上購物來說,HTTP協議是指的那個快遞單,你寄件的時候填的單子就像是發了一個HTTP請求,等貨物運到地方了,快遞員會根據你發的請求把貨物送給相應的收貨人。而TCP協議就是中間運貨的那個大貨車,也可能是火車或者飛機,但不管是什么,它是負責運輸的,因此必須要有路,不管是地上還是天上。那么這個路就是所謂的TCP連接,也就是一個雙向的數據通道。
因此,LZ現在甚至覺得,“HTTP連接”這個詞就不應該出現,它只是一個應用層的協議,根本就沒有所謂的連接這一說,就像FTP也是應用層的協議,但是你有聽說過FTP連接嗎?(恩,好像是聽過,-_-,但你現在知道了,其實所謂的FTP連接,嚴格來說,依舊是TCP連接)
實際上,說HTTP請求和HTTP響應會更准確一些,而HTTP請求和HTTP響應,都是通過TCP連接這個通道來回傳輸的。
不管怎么說,一定要務必記住,長連接是指的TCP連接,而不是HTTP連接。
一個疑問
之前LZ一直對一件事有些模糊不清,首先是怎么樣就算是把HTTP變成長連接了,是不是只要設置Connection為keep-alive就算是了?
如果是的話,那都說HTTP1.1默認是長連接,而觀察我們平時開發的Web應用的HTTP頭部,Connection也確實是keep-alive,那就是說我們大部分都是用的長連接,但是長連接不是一般用於交互比較頻繁的應用嗎?像我們這種普通的Web應用,比如博客園這種,或者我的個人博客這種,長連接有什么用?
如果有用那用處到底是什么,我們又不是客戶端與服務器交互頻繁的那種應用(畢竟你打開網頁肯定要半天才打開另外一個吧),如果沒用的話,那到底應不應該把Connection為keep-alive這個header值給改掉,從而改成短連接?
這個疑問,在LZ明白了長連接其實是指的TCP連接之后,基本上就明白了。而這個疑問,也正是LZ在“以前的誤解”那一段所提到的,那個因為誤解導致LZ一直搞不明白的問題。
為什么解決了上面那個誤解之后,前面所說的這些疑問LZ都明白了?
因為長連接意味着連接會被復用,畢竟一直保持着連接不就是為了重復使用嘛。但如果長連接是指的HTTP的話,那就是說HTTP連接可以被重復利用,這個話聽起來就感覺很別扭。之所以覺得別扭,其實就是LZ的一種直覺,沒什么理論依據。而這種別扭的根源就在於,之前一直沒有融會貫通的感覺,所以總感覺缺少點什么。不過這點疑惑,並沒有影響LZ的工作,因此也就沒深究過。
但現在好了,明白了長連接實際上是指的TCP連接,LZ瞬間自己就想明白了上面的那些問題。
第一個問題是,是不是只要設置Connection為keep-alive就算是長連接了?
當然是的,但要服務器和客戶端都設置。
第二個問題是,我們平時用的是不是長連接?
這個也毫無疑問,當然是的。(現在用的基本上都是HTTP1.1協議,你觀察一下就會發現,基本上Connection都是keep-alive。而且HTTP協議文檔上也提到了,HTTP1.1默認是長連接,也就是默認Connection的值就是keep-alive)
第三個問題,也是LZ之前最想不明白的問題,那就是我們這種普通的Web應用(比如博客園,我的個人博客這種)用長連接有啥好處?需不需要關掉長連接而使用短連接?
這個問題LZ現在終於明白了,問題的答案是好處還是有的。
好處是什么?
首先,剛才已經說了,長連接是為了復用,這個在之前LZ就明白。那既然長連接是指的TCP連接,也就是說復用的是TCP連接。那這就很好解釋了,也就是說,長連接情況下,多個HTTP請求可以復用同一個TCP連接,這就節省了很多TCP連接建立和斷開的消耗。
比如你請求了博客園的一個網頁,這個網頁里肯定還包含了CSS、JS等等一系列資源,如果你是短連接(也就是每次都要重新建立TCP連接)的話,那你每打開一個網頁,基本要建立幾個甚至幾十個TCP連接,這浪費了多少資源就不用LZ去說了吧。
但如果是長連接的話,那么這么多次HTTP請求(這些請求包括請求網頁內容,CSS文件,JS文件,圖片等等),其實使用的都是一個TCP連接,很顯然是可以節省很多消耗的。
這樣一解釋,就很明白了,不知道大家看了這些解釋感覺如何,反正LZ在自己想明白以后,有種豁然開朗的感覺。
另外,最后關於長連接還要多提一句,那就是,長連接並不是永久連接的。如果一段時間內(具體的時間長短,是可以在header當中進行設置的,也就是所謂的超時時間),這個連接沒有HTTP請求發出的話,那么這個長連接就會被斷掉。
這一點其實很容易理解,否則的話,TCP連接將會越來越多,直到把服務器的TCP連接數量撐爆到上限為止。現在想想,對於服務器來說,服務器里的這些個長連接其實很有數據庫連接池的味道,大家都是為了節省連接重復利用嘛,對不對?
什么時候用長連接,短連接?
- 長連接多用於操作頻繁,點對點的通訊,而且連接數不能太多情況,。每個TCP連接都需要三步握手,這需要時間,如果每個操作都是先連接,再操作的話那么處理速度會降低很多,所以每個操作完后都不斷開,次處理時直接發送數據包就OK了,不用建立TCP連接。例如:數據庫的連接用長連接, 如果用短連接頻繁的通信會造成socket錯誤,而且頻繁的socket 創建也是對資源的浪費。
- 而像WEB網站的http服務一般都用短鏈接,因為長連接對於服務端來說會耗費一定的資源,而像WEB網站這么頻繁的成千上萬甚至上億客戶端的連接用短連接會更省一些資源,如果用長連接,而且同時有成千上萬的用戶,如果每個用戶都占用一個連接的話,那可想而知吧。所以並發量大,但每個用戶無需頻繁操作情況下需用短連好。
長連接與短連接區別:
長連接:連接→數據傳輸→保持連接(心跳)→數據傳輸→保持連接(心跳)→……→關閉連接(一個TCP連接通道多個讀寫通信);
短連接:連接→數據傳輸→關閉連接;