心跳包必要性與策略選擇

一、CS模型中如何相互知曉狀態

爲什麼需要心跳包?

在傳統的CS模型中,客戶端與服務端相互發送消息的過程中,是需要知道相互之間的狀態的,因爲客戶端隨時可能給服務端發送消息。在聊天過程中,是不可能客戶端隨時給服務端發送消息,真實情況是服務端收到某個客戶端的消息之後推送過來。在這個過程中,服務器需要知道客戶端是否可用的。

服務端要想知道客戶端是否可用,最大的問題在於可能客戶端異常地斷開了,但是服務器沒有收到斷開的這個情況,所以服務器沒有釋放這個socket,它認爲還連接着,此時,他會向該客戶端發送消息,而在發送消息之後會發生異常。其實該過程是一個浪費的,因爲服務端已準備好數據準備發送,但是發送的時候才失敗,現在重新進行一個重連,重新創建數據包,這是一個非常浪費的過程。這是我們需要心跳包的原因。

 

二、從TCP理論來說不需要心跳包-客戶端服務器直連

如果將客戶端與服務端同時部署在自己的電腦上,兩個進程之間通過socket相互傳遞消息的時候,這時候是不需要心跳包來維持的。只要進程不斷開,隨時可用發送和接收數據。

 

需要心跳包的情況:

--程序崩潰、防火牆

--網絡運營商(ISP) --> NAT路由器(映射狀態表)

 

程序崩潰的時候,可能會觸發服務端沒有收到程序崩潰的情況,服務端也不知道需要釋放客戶端的資源。

計算機與計算機之間相互是有防火牆的,而這個防火牆隨時可以做到一個策略,隨時可以斷開socket連接,而斷開的時候可能不會進行四次揮手,服務端或者客戶端沒有收到連接斷開的消息,此時會認爲連接還可用,隨時還想發送數據,發送的時候才知道連接不可用。

引起網絡斷開的大頭是網絡運營商ISP,它在傳輸數據的過程中有一個東西叫NAT路由器。路由器的主要作用是將客戶端所有的狀態通過NAT路由器進行映射,然後再通過映射的端口進行連接服務器,這個過程中存在一個映射表過期的情況,一旦映射表過期了,就是數據不能通過NAT路由器進行轉發了,所以數據最終發送的時候會出現無法發送的情況,此時socket連接也是連接異常的狀態。此時,socket連接是接收不到斷開連接的消息的。

 

三、NAT路由器的原理

ISP是網絡運營商,它有一個非常大型的路由器,這個大型路由器組建了一個大型局域網,大型局域網連接了所有的電腦、手機、打印機等所有可以聯網的設備,甚至也可以是路由器。家裏的路由器就是連接到了網絡運營商的大型路由器上。每個電腦都被分配了局域網的某個ip地址,以及通信都是連接到路由器上面的。這樣的情況下,比如電腦的ip 192.168.0.101其實是局域網的ip地址,它僅僅只是在路由器上掛了一個號,用於說明它是路由器下面的哪個子的電腦。

路由器有一個對外的公共的ip地址 82.10.250.19,服務器也是一個外網地址,兩個外網地址之間是可以直接進行連接的。連接之後所有的信息都是通過路由器進行傳輸的,也就是說對服務器而言,所有的電腦設備都是被屏蔽的,它只知道有一個大的客戶端向它進行了連接,這個大的客戶端就是82.10.250.19。

 

四、電腦與服務器之間的連接

電腦通過局域網連接路由器,這個路由器有一個全局對外的ip地址82.10.250.19,然後通過網絡運營商連接到server服務器。Server的ip地址一定是公網的ip地址纔可以連接到。如果服務端是局域網的ip地址的話,對於NAT路由器來說是無法訪問到的,它必須連接到對外的公共的ip地址。

 

五、NAT路由器的映射表

1、

對於某個客戶端而言,只要客戶端的ip地址沒變,同時客戶端對外的端口沒變,那麼NAT路由器對外公佈的往其它Server連接的ip和地址將不會改變。也就是說,一個客戶端通過NAT路由器之後,如果此時NAT路由器是一個80端口,那麼它連接到server1的時候使用的是80端口去連接,連接到server2的時候也是使用80端口去連接。只要客戶端的ip地址和端口不變,那麼它就將是這樣一個結構。

這樣的結構是一個一對多的結構,對於NAT路由器而言,它是一個一對多的(多個服務端)。

這樣的結構安全性是比較低的,因爲只要客戶端的ip地址和端口不變,那麼NAT路由器的ip地址和端口就不變,那麼Server1、Server2只要連接過一次客戶端,那麼它就可以反向連接客戶端。也就是說,可以通過client連接server1,也可以通過server2來主動反向連接client,這是一個雙向的方式。這樣的方式,數據傳輸快,但是安全性較低。

2、

客戶端ip和端口不變,但是連接的server端是變化的,那麼它對外的端口就是不同的。server1只能通過上面的端口來收發數據,Server2也只能通過下面的端口來收發數據。如果Server2想通過Server1的端口來反向連接客戶端,是不會成功的。因此,它的安全性相對來說比較高。

 

六、NAT超時時間

如果移動在3G/2G網絡下,如果數據在5分鐘之內不進行任何的數據收發,那麼,NAT內部維持的映射表將會自動被刪除掉。所以,必須在5分鐘之內進行一次數據的收發,確保維持這個映射表。其它依次類推。

 

七、心跳包的作用

客戶端與服務器之間相互告知狀態

通過定時發送信息,讓中間的運營商的NAT路由表得以維持;避免路由表過期帶來的異常中斷

由於其約定性、定時性所以稱爲心跳包

 

八、心跳策略選擇

1、

TCP :  KeepAlive 7200 2H ACK(每間隔7200s發送一次,2小時發送一次,發送之後會有ACK的回送包,從而達到確認連接活躍性的目的)

TCP : KeepAlive僅代表連接得以保持,而不代表對方的業務層是否可以消費數據

(當兩個socket連接之後,當一個socket給另一個socket發送一個keepalive連接消息的時候,這個數據包僅僅只在TCP的傳輸層就被消費掉了,然後回送一個ack的回送包,但是這個消息並不會上升到業務層。這樣的機制可以確保對上層的無感知性,但同時不能保證業務層已經崩潰了。業務層可能由於某些原因導致死鎖或者宕機,而底層的socket連接還是暢通的,這種情況下整個系統是癱瘓的,但是通過KeepAlive進行連接,此時得到的狀態是正常的。這種情況是不對的,應該得到系統的準確狀態,同時,由於每隔2個小時發送一次,此時運營商NAT的連接早已中斷了,這個連接一般而言發送這個KeepAlive消息的時候收到的是已經錯誤中斷的消息)

HTTP : Keep-Alive 意圖在於連接複用,同一個連接上串行方式傳遞請求-響應數據

2、

這個數據包只能發送一個字節,傳遞的是一個int值,取的是低八位。

另一個客戶端可以通過SO_OOBINLINE來設置是否感知業務層。但是如果要感知業務層,需要把它往業務層拋去 ,業務層收到這個數據之後,由於它的區間是在0~255之間,跟整個業務層的衝撞是非常非常大的,從而導致整個業務層的邏輯進行調整,這是非常危險的,一般不這樣處理。

但是也可以不往業務層拋,僅僅用來確認連接是否可靠,此時,比前面的KeepAlive更加優秀。

 

九、心跳數據包

 

十、

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章