1. 程式人生 > >HTTP長連線與短連結以及推送技術原理

HTTP長連線與短連結以及推送技術原理

HTTP長連線和短連線以及推送服務原理
HTTP長連線和短連線1
1. HTTP協議與TCP/IP協議的關係

  HTTP的長連線和短連線本質上是TCP長連線和短連線。HTTP屬於應用層協議,在傳輸層使用TCP協議,在網路層使用IP協議。IP協議主要解決網路路由和定址問題,TCP協議主要解決如何在IP層之上可靠的傳遞資料包,使在網路上的另一端收到發端發出的所有包,並且順序與發出順序一致。TCP有可靠,面向連線的特點。

2. 如何理解HTTP協議是無狀態的

 HTTP協議是無狀態的,指的是協議對於事務處理沒有記憶能力,伺服器不知道客戶端是什麼狀態。也就是說,開啟一個伺服器上的網頁和你之前開啟這個伺服器上的網頁之間沒有任何聯絡。HTTP是一個無狀態的面向連線的協議,無狀態不代表HTTP不能保持TCP連線,更不能代表HTTP使用的是UDP協議(無連線)。

3. 什麼是長連線、短連線?

  在HTTP/1.0中,預設使用的是短連線。也就是說,瀏覽器和伺服器每進行一次HTTP操作,就建立一次連線,但任務結束就中斷連線。如果客戶端瀏覽器訪問的某個HTML或其他型別的 Web頁中包含有其他的Web資源,如JavaScript檔案、影象檔案、CSS檔案等;當瀏覽器每遇到這樣一個Web資源,就會建立一個HTTP會話。

但從 HTTP/1.1起,預設使用長連線,用以保持連線特性。使用長連線的HTTP協議,會在響應頭有加入這行程式碼:
Connection:keep-alive
在使用長連線的情況下,當一個網頁開啟完成後,客戶端和伺服器之間用於傳輸HTTP資料的 TCP連線不會關閉,如果客戶端再次訪問這個伺服器上的網頁,會繼續使用這一條已經建立的連線。Keep-Alive不會永久保持連線,它有一個保持時間,可以在不同的伺服器軟體(如Apache)中設定這個時間。實現長連線要客戶端和服務端都支援長連線。
HTTP協議的長連線和短連線,實質上是TCP協議的長連線和短連線。
3.1 TCP連線

   當網路通訊時採用TCP協議時,在真正的讀寫操作之前,server與client之間必須建立一個連線,當讀寫操作完成後,雙方不再需要這個連線 時它們可以釋放這個連線,連線的建立是需要3次握手的,而釋放則需要4次握手,所以說每個連線的建立都是需要資源消耗和時間消耗的。 

  
3.2 TCP短連線

      我們模擬一下TCP短連線的情況,client向server發起連線請求,server接到請求,然後雙方建立連線。client向server 傳送訊息,server迴應client,然後一次讀寫就完成了,這時候雙方任何一個都可以發起close操作,不過一般都是client先發起 close操作。為什麼呢,一般的server不會回覆完client後立即關閉連線的,當然不排除有特殊的情況。從上面的描述看,短連線一般只會在 client/server間傳遞一次讀寫操作

短連線的優點是:管理起來比較簡單,存在的連線都是有用的連線,不需要額外的控制手段。
3.3 TCP長連線

   接下來我們再模擬一下長連線的情況,client向server發起連線,server接受client連線,雙方建立連線。Client與server完成一次讀寫之後,它們之間的連線並不會主動關閉,後續的讀寫操作會繼續使用這個連線。

首先說一下TCP/IP詳解上講到的TCP保活功能,保活功能主要為伺服器應用提供,伺服器應用希望知道客戶主機是否崩潰,從而可以代表客戶使用資源。如果客戶已經消失,使得伺服器上保留一個半開放的連線,而伺服器又在等待來自客戶端的資料,則伺服器將應遠等待客戶端的資料,保活功能就是試圖在服務 器端檢測到這種半開放的連線。
如果一個給定的連線在兩小時內沒有任何的動作,則伺服器就向客戶發一個探測報文段,客戶主機必須處於以下4個狀態之一:
客戶主機依然正常執行,並從伺服器可達。客戶的TCP響應正常,而伺服器也知道對方是正常的,伺服器在兩小時後將保活定時器復位。
客戶主機已經崩潰,並且關閉或者正在重新啟動。在任何一種情況下,客戶的TCP都沒有響應。服務端將不能收到對探測的響應,並在75秒後超時。伺服器總共傳送10個這樣的探測 ,每個間隔75秒。如果伺服器沒有收到一個響應,它就認為客戶主機已經關閉並終止連線。
客戶主機崩潰並已經重新啟動。伺服器將收到一個對其保活探測的響應,這個響應是一個復位,使得伺服器終止這個連線。
客戶機正常執行,但是伺服器不可達,這種情況與2類似,TCP能發現的就是沒有收到探查的響應。
3.4 長連線短連線操作過程

短連線的操作步驟是:
建立連線——資料傳輸——關閉連線…建立連線——資料傳輸——關閉連線
長連線的操作步驟是:
建立連線——資料傳輸…(保持連線)…資料傳輸——關閉連線
4. 長連線和短連線的優點和缺點
由上可以看出,長連線可以省去較多的TCP建立和關閉的操作,減少浪費,節約時間。對於頻繁請求資源的客戶來說,較適用長連線。不過這裡存在一個問題,存活功能的探測週期太長,還有就是它只是探測TCP連線的存活,屬於比較斯文的做法,遇到惡意的連線時,保活功能就不夠使了。在長連線的應用場景下,client端一般不會主動關閉它們之間的連線,Client與server之間的連線如果一直不關閉的話,會存在一個問題,隨著客戶端連線越來越多,server早晚有扛不住的時候,這時候server端需要採取一些策略,如關閉一些長時間沒有讀寫事件發生的連線,這樣可 以避免一些惡意連線導致server端服務受損;如果條件再允許就可以以客戶端機器為顆粒度,限制每個客戶端的最大長連線數,這樣可以完全避免某個蛋疼的客戶端連累後端服務。
短連線對於伺服器來說管理較為簡單,存在的連線都是有用的連線,不需要額外的控制手段。但如果客戶請求頻繁,將在TCP的建立和關閉操作上浪費時間和頻寬。
長連線和短連線的產生在於client和server採取的關閉策略,具體的應用場景採用具體的策略,沒有十全十美的選擇,只有合適的選擇。
5. 什麼時候用長連線,短連線?
長連線多用於操作頻繁,點對點的通訊,而且連線數不能太多情況,。每個TCP連線都需要三步握手,這需要時間,如果每個操作都是先連線,再操作的話那麼處理速度會降低很多,所以每個操作完後都不斷開,次處理時直接傳送資料包就OK了,不用建立TCP連線。例如:資料庫的連線用長連線, 如果用短連線頻繁的通訊會造成socket錯誤,而且頻繁的socket 建立也是對資源的浪費。
而像WEB網站的http服務一般都用短連結,因為長連線對於服務端來說會耗費一定的資源,而像WEB網站這麼頻繁的成千上萬甚至上億客戶端的連線用短連線會更省一些資源,如果用長連線,而且同時有成千上萬的使用者,如果每個使用者都佔用一個連線的話,那可想而知吧。所以併發量大,但每個使用者無需頻繁操作情況下需用短連好。
推送服務
維基百科:2
推送技術,又名反向AJAX,指的是一種基於Internet,將由中心或釋出者發出訊息傳輸給使用者的技術。與之相對的是拉取(參見AJAX),這種情況下請求是由使用者或客戶端主動發起的。

  當我們開發需要和伺服器互動的應用程式時,基本上都需要獲取伺服器端的資料,比如《地震應急通》就需要及時獲取伺服器上最新的地震資訊。要獲取伺服器上不定時更新的資訊,一般來說有兩種方法:第一種是客戶端使用Pull(拉)的方式,就是隔一段時間就去伺服器上獲取一下資訊,看是否有更新的資訊出現。第二種就是 伺服器使用Push(推送)的方式,當伺服器端有新資訊了,則把最新的資訊Push到客戶端上。這樣,客戶端就能自動的接收到訊息。 

雖然Pull和Push兩種方式都能實現獲取伺服器端更新資訊的功能,但是明顯來說Push方式比Pull方式更優越。因為Pull方式更費客戶端的網路流量,更主要的是費電量,還需要我們的程式不停地去監測服務端的變化。 
在開發Android和iPhone應用程式時,我們往往需要從伺服器不定的向手機客戶端即時推送各種通知訊息。我們只需要在Android或IPhone的通知欄處向下一拉,就展開了Notification Panel,可以集中一覽各種各樣通知訊息。目前iOS平臺上已經有了比較簡單的和完美的推送通知解決方案,可是Android平臺上實現起來卻相對比較麻煩。
3 我們首先了解一下為什麼移動端維護長連線需要心跳機制。我們知道,維護任何一個長連線都需要心跳機制,客戶端傳送一個心跳給伺服器,伺服器給客戶端一個心跳應答,這樣就形成客戶端伺服器的一次完整的握手,這個握手是讓雙方都知道他們之間的連線是沒有斷開,客戶端是線上的。如果超過一個時間的閾值,客戶端沒有收到伺服器的應答,或者伺服器沒有收到客戶端的心跳,那麼對客戶端來說則斷開與伺服器的連線重新建立一個連線,對伺服器來說只要斷開這個連線即可。那麼在智慧手機上的長連線心跳和在Internet上的長連線心跳有什麼不同的目的呢?原因就在於智慧手機使用的是移動無線網路,那麼我們在講長連線之前我們首先要了解無線行動網路的特點。4

1.無線行動網路的特點:
當一臺智慧手機連上行動網路時,其實並沒有真正連線上Internet,運營商分配給手機的IP其實是運營商的內網IP,手機終端要連線上Internet還必須通過運營商的閘道器進行IP地址的轉換,這個閘道器簡稱為NAT(NetWork Address Translation),簡單來說就是手機終端連線Internet 其實就是移動內網IP,埠,外網IP之間相互對映。相當於在手機終端在移動無線網路這堵牆上打個洞與外面的Internet相連。
GGSN(GateWay GPRS Support Note 閘道器GPRS支援節點)模組就實現了NAT功能,由於大部分的移動無線網路運營商為了減少閘道器NAT對映表的負荷,如果一個鏈路有一段時間沒有通訊時就會刪除其對應表,造成鏈路中斷,正是這種刻意縮短空閒連線的釋放超時,原本是想節省通道資源的作用,沒想到讓網際網路的應用不得以遠高於正常頻率傳送心跳來維護推送的長連線。這也是為什麼會有之前的信令風暴,微信搖收費的傳言,因為這類的應用傳送心跳的頻率是很短的,既造成了通道資源的浪費,也造成了手機電量的快速消耗。

2.Android系統的推送和iOS的推送有什麼區別:
首先我們必須知道,所有的推送功能必須有一個客戶端和伺服器的長連線,因為推送是由伺服器主動向客戶端傳送訊息,如果客戶端和伺服器之間不存在一個長連線那麼伺服器是無法來主動連線客戶端的。因而推送功能都是基於長連線的基礎是上的。
iOS長連線是由系統來維護的,也就是說蘋果的iOS系統在系統級別維護了一個客戶端和蘋果伺服器的長連結,iOS上的所有應用上的推送都是先將訊息推送到蘋果的伺服器然後將蘋果伺服器通過這個系統級別的長連結推送到手機終端上,這樣的的幾個好處為:

1.在手機終端始終只要維護一個長連線即可,而且由於這個長連結是系統級別的不會出現被殺死而無法推送的情況。

2.省電,不會出現每個應用都各自維護一個自己的長連線。

3.安全,只有在蘋果註冊的開發者才能夠進行推送,等等。
Android的長連線是由每個應用各自維護的,但是Google也推出了和蘋果技術架構相似的推送框架,C2DM,雲端推送功能,但是由於Google的伺服器不在中國境內,其他的原因你懂的。所以導致這個推送無法使用,Android的開發者不得不自己去維護一個長連結,於是每個應用如果都24小時線上,那麼都得各自維護一個長連線,這種電量和流量的消耗是可想而知的。雖然國內也出現了各種推送平臺,但是都無法達到只維護一個長連線這種消耗的級別。

3.推送的常見實現方式:
輪詢(Pull)方式:即輪詢(polling),客戶端不斷的查詢伺服器,檢索新內容。
持久連線(Push)方式:即繫結(binding),客戶端和伺服器之間維持一個TCP/IP長連線,伺服器向客戶端push。
SMS(Push)方式:伺服器又新內容時,傳送一條類似簡訊的信令給客戶端,客戶端收到後從伺服器中下載新內容,也就是SMS的推送方式。
蘋果的推送系統和GoogleC2DM(Cloud to Device Messaging)推送系統其實都是在系統級別維護一個TCP/IP長連線,都是基於第二種的方式進行推送的。該方案可以解決由輪詢帶來的效能問題,但是還是會消耗手機的電池。iOS平臺的推送服務之所以工作的很好,是因為每一臺手機僅僅保持一個與伺服器之間的連線,事實上GoogleC2DM也是這麼工作的。
目前GoogleC2DM已經被Google雲訊息傳遞(英語:Google Cloud Messaging,簡稱GCM)所取代,但在國內在實際使用中使用GCM的並不太多,以下是備選方案參考:
使用XMPP協議(Openfire + Spark + Smack)
使用MQTT協議
第三種方式由於運營商沒有免費開放,這種信令導致了這種推送在成本上是無法接受的,雖然這種推送的方式非常的穩定,高效和及時。