栗永勝 崔佳冬 秦會斌
(杭州電子科技大學新型電子器件與應用研究所 浙江 杭州 310000)
現代通信系統中,為實現移動終端、嵌入式終端等無線設備客戶端與服務器通信的實時性,需要終端設備的客戶端與服務器保持TCP長連接[1]。由于NAT超時、DHCP過期、路由節點異常等會造成客戶端與服務器通信鏈路的中斷,在TCP通信中兩端無法及時感知鏈路異常中斷情況,影響通信的可靠性。
在TCP通信中采用應用層定時發送心跳包的方式保持連接的存活。谷歌的GCM服務、蘋果的APNs、MQTT協議等都采用固定間隔發送心跳包的方式來保持長連接,該方式實現簡單,但存在以下缺點:(1) 無法適應復雜的網絡環境。固定心跳包的發送時間間隔值往往根據經驗值設定,無法適應終端設備所處環境,若該值設置過長會影響系統的可靠性、實時性。(2) 造成資源浪費。為確保系統的可靠該值設定較小,造成了流量、電量、網絡等資源的浪費。
針對以上問題,本文提出了一種自適應心跳保持長連接的方法。程序根據網絡質量、用戶設置學習心跳包發送時間間隔值,能夠適應不同的網絡環境,學習到的心跳間隔在保證連接可靠的前提下,盡可能大,從而節省了流量、電量等資源。
嵌入式網關、智能手機應用消息推送等實時通信系統中,服務器需要根據連接將消息推送至客戶端。IPv4的IP地址有限,無法為每一個終端設備分配一個公有IP地址。大部分終端設備通過NAT將私有IP映射為公有IP,通過修改數據包中IP地址完成NAT內部設備和外部終端之間的通信,NAT采用動態刷新的方式為需要連接互聯網的設備分配可用的公有IP。如果外部終端和服務器所建立鏈路長時間空閑,NAT刪除與之相對應的記錄,導致鏈路中斷。所以在需要保持長連接的應用場景中采用在應用層發送心跳包的方法來保持終端設備和服務器鏈路的存活[2]。
圖1為通信系統中心跳包等報文傳輸鏈路,鏈路1為終端設備向服務器發送心跳包數據,由終端設備根據服務器的IP及端口號發起連接。當服務器主動向終端設備推送信息或回復終端請求時通過鏈路2傳輸,若要保持鏈路1、2的暢通,則需要終端設備發送心跳包來維持鏈接。

圖1 系統通信鏈路模型
心跳包和回復幀會消耗流量,計算式為:
(1)
式中:fc單位為Byte/h,ti為心跳間隔,單位為秒,ms為發送端發送心跳包的大小,mr為心跳包接收端回復的確認幀的大小,ms與mr的單位為Byte。
電量消耗ec計算公式:
ec=ew+es
(2)
式中:es為系統睡眠時電量消耗,ew為系統工作時電量消耗,ew≥es,通過減少心跳包次數可以減少系統的工作時間,從而減少電量的消耗。
從式(1)、式(2)中可以看出,ti越大,fc、ec越小,流量、電量消耗越少。可以通過提高ti減少心跳包對資源的消耗。
心跳間隔過小,心跳包發送頻繁會造成電量、流量、網絡資源的浪費;心跳間隔過大會影響系統的穩定性,不能保證通信的實時性。根據以上問題,自適應算法應遵循以下原則[3]:
(1) 提升通信鏈路的穩定性,盡可能減小由NAT超時、DHCP過期、路由節點異常等引起的鏈路中斷時間;
(2) 在保證鏈路穩定性的情況下,心跳間隔應盡可能大,減少交互開銷,節省流量、電量等;
(3) 提升對連接中斷的響應速度,以較短的時間完成對鏈接中斷的判斷,重新連接上服務器。
根據以上原則自適應算法設計包括心跳間隔自適應、最優心跳間隔判斷、鏈路中斷判斷三個模塊。心跳包自適應調節系統具有自適應和穩定工作兩種工作模式,根據條件切換。
(1) 心跳間隔自適應。心跳間隔自適應模塊對計算得到的心跳間隔進行測試,連續成功N次后,根據算法增加心跳間隔,定義為自適應增過程;心跳包在測試過程中第一次出現失敗,則根據算法減小心跳間隔,定義為自適應減過程。
(2) 最優心跳間隔判斷模塊。測試時當心跳間隔達到最優心跳間隔條件則退出自適應模式,且在一段時間內不再改變。
(3) 鏈路中斷判斷模塊。心跳包發送失敗時向服務器發送測試報文,若在規定的時間內未收到回復幀則表示鏈路中斷,需對間隔值進行調節。
設To為最優心跳間隔,ti為測試心跳間隔,Tt為用戶定義閾值,T0∈[Tmin,Tmax],系統在自適應學習模式下通過不斷縮小To查找范圍,使心跳間隔逼近To,當ti與To誤差小于等于Tt時可認為ti為最優心跳間隔。根據算法計算要測試的心跳間隔ti,并測試ti是否可以保持通信鏈路的“存活”,若可以保活則將To自適應范圍下限改為ti,否則將To自適應范圍上限變為ti。下面對查找最優心跳間隔To進行詳細介紹。
心跳間隔的學習范圍初始為[Tmin,Tmax],可根據需求進行設置。Tmin與Tmax可相等,此時最優心跳間隔為Tmin,無需自適應調整。在查找最優心跳間隔To的學習過程中使用二分法將查找范圍折半[4],記為[tl_min,tl_max),To∈[tl_min,tl_max),且[tl_min,tl_max)∈[Tmin,Tmax]。其中tl_min為自適應過程中當前的最大成功心跳間隔,tl_max為當前最小失敗心跳間隔。To范圍上限tl_max計算公式:
(3)
To范圍下限tl_min計算公式為:
(4)
式(3)中tl_max初試值為Tmax,tii為測試中失敗的心跳間隔的最小值。式(4)中tl_min初試值為Tmin,tii為測試中成功的心跳間隔的最大值。
自適應過程中當測試心跳間隔需要增大時,由下式計算得到測試心跳間隔tii:
(5)
自適應過程中當心跳間隔需減小時,測試心跳間隔tii計算式為:
(6)
tii為當前測試心跳間隔,To查找范圍為[tl_min,tl_max)。Tt為閾值。
當To的范圍[tl_min,tl_max)上限與下限的差值小于閾值Tt時,結束自適應過程,以tii作為心跳間隔進入穩定工作模式,tii與To的誤差小于Tt。
TCP通信中往返門限值根據往返時延RTT(Round Trip Time)計算。RTT為終端發送數據到終端接收到回復幀所花費的時間,由終端處理時間、鏈路傳輸時間、路由緩存排隊處理時間組成[5],RTT反映了系統資源使用和網絡擁塞情況。

(7)

(8)
報文往返門限值為tw,文中定義tw計算公式如下:
(9)

穩定工作過程中通過心跳包發送失敗率判斷是否重新開啟自適應,計算心跳包發送失敗率ρ:
(10)
nfail、ntotal分別為穩定工作工程中心跳包失敗的個數、心跳包總個數。用戶可以通過設置ρ來調節系統的穩定性ρ的范圍為[0,1]。
在自適應模式下,系統根據算法進行查找最優心跳間隔,具體步驟如下:
(1) 初試化自適應范圍為[Tmin,Tmax],判斷Tmin、Tmax是否相等,若相等則進入步驟(6),否則執行步驟(2);
(2) 獲得往返時延RTT,并根據式(9)計算通信往返門限值tw;
(3) 由式(5)獲得測試的心跳間隔tii,以tii為心跳間隔進行測試;
(4) 步驟(3)測試成功,將測試范圍的下限tl_min賦值為tii,若步驟(3)測試失敗,則根據式(6)計算下一個測試心跳間隔,將測試范圍的上限tl_max改為tii;
(5) 根據條件判斷是否為最優心跳間隔,不滿足最優心跳間隔條件則重復步驟(3)、步驟(4),若滿足最優心跳間隔條件,則以當前值心跳間隔,退出自適應學習模式,系統進入穩定工作模式;
(6) 穩定工作模式統計最優心跳間隔的失敗個數,判斷是否重新開啟自適應模式。
測試系統通信的網絡層使用TCP協議,且設計了應用層通信協議。在中國移動、中國聯通GPRS網絡下對本自適應算法進行了測試。
心跳包及心跳包回復幀應用層協議字段如表1所示,包括協議頭、數據長度、用戶數據、協議尾4個字段。

表1 應用層協議字段
數據長度字段為用戶數據字段BASE64編碼后長度。該字段經過字節擴展技術處理,既將4字節的int類型變為8字節字符類型,例如1字節的0x6A,字節擴展后變為“6”、“A”字符,共2字節。字節擴展后,數據長度字段僅出現0~9、A~F或a~f等字符。
心跳包報文用戶數據字段主要包括報文序列號、功能碼、時間、當前心跳值。回復幀包括報文序列號、功能碼、學習范圍的最大值與最小值、最優間隔閾值。將最小值Tmin、最大值Tmax放到協議里由服務器配置使系統自適應更具靈活性。用戶數據字段使用BASE64編碼后包含A~Z、a~z、0~9、+、-等64個字符[8-9]。
經字節擴展和BASE64編碼處理后,避免“@”、“&”等字符出現在用戶數據字段和數據長度字段里,程序通過判斷協議頭、尾,正確識別協議包,有效解決了TCP/IP通信中常見的斷包、粘包問題。圖2為協議包舉例,數據長度為16字節。

圖2 協議舉例
測試系統客戶端用C語言開發,運行在ARM嵌入式系統。測試服務器使用Java語言開發,云服務器對來自客戶端的心跳包等數據進行解析并回復。
圖3為程序的流程。
程序包括初始化參數、建立連接、計算往返門限值、查找及測試心跳間隔、鏈路中斷判斷等步驟。首先,客戶端與測試服務器建立請求,獲得初始的自適應學習范圍[Tmin,Tmax]為[60,1 200],并設置閾值Tt為4,即當自適應心跳間隔查找范圍小于等于4時,判定測試成功的心跳間隔等價于To。其次,根據算法計算心跳間隔,并對心跳間隔進行測試。最后,根據閾值Tt判斷進入穩定工作模式,檢測開啟自適應條件。
網絡socket通信中使用epoll事件驅動機制監視網絡通信事件。定時任務使用基于Linux C的clock_gettime()函數完成,精度為納秒。將clock_gettime()配置為CLOCK_MONOTONIC,既從系統啟動開始計時,用戶改變系統時間不影響該值。
查找最優間隔偽代碼如下:
void self_adaption_fun(){
if(is_success){
//將自適應范圍下限變為當前心跳間隔
//范圍閾值判斷
if(LEARN_MAX-LEARN_MIN<=Th){
//進入穩定工作狀態
return;
}
//根據式(5)增加心跳間隔
}else if(!is_success){
//將自適應范圍上限變為當前心跳間隔
//根據式(6)減小心跳間隔
}
}
本算法在中國移動和中國聯通GPRS網絡下進行了測試。中國移動GPRS網絡下測得如表2數據,經過9次查找測試,范圍縮小至[897,901),此時范圍長度為4與閾值Tt相等,此時tii與To的誤差小于4,判定最優心跳間隔To?ti,系統以897 s為心跳間隔進入穩定工作模式。

表2 移動GPRS網絡下算法測試數據 s
在中國聯通GPRS網絡下測得的數據如表3所示,經過10次測試,確定最優心跳間隔的范圍為[600,603),范圍的長度由1 140縮小至3,tii與To的誤差小于3,600 s可作為穩定工作狀態的心跳間隔。

表3 聯通GPRS網絡下算法測試數據 s
圖4為聯通和移動GPRS網絡的RTT情況,從圖中可以看出網絡抖動較大。表4對數據RTT數據進行了分析,并給出了式(9)的系數的值。

圖4 中國移動和聯通GPRS網絡下RTT統計


表4 網絡RTT分析 s
經過多次測試在中國移動和中國聯通GPRS網絡下系統可以較快地查找到合適的心跳間隔,算法能夠很好地適應不同的網絡環境。中國移動GPRS網絡下的心跳間隔約為聯通GPRS網絡的1.5倍。
本文提出了一種自適應的心跳包發送間隔值查找方法,本方法可根據網絡環境調節心跳包發送間隔,減少了由于發送心跳包帶來的開銷。經過測試本方法穩定可靠,適用于移動終端、嵌入式網關等設備。本文提出的方法靈活易用性強,開發人員可根據需求通過配置參數調節穩定性和節省資源的效率。由于實驗條件的限制本系統還有許多需要改善的地方,例如需要對更多的網絡類型進行測試,可以將GPRS等網絡的網絡質量作為調節心跳間隔的條件,提高算法性能。
[1] 深圳市合信自動化技術有限公司.一種心跳間隔自動調整的方法和網關設備、服務器:中國,2014104127389[P].2014-12-24.
[2] 騰訊科技(深圳)有限公司.智能心跳保活方法及智能心跳保活系統:中國,2014102989780[P].2016-04-13.
[3] 溫彬民.一種基于自適應心跳機制的MQTT通信協議的研究與應用[D].華南理工大學,2015:60.
[4] 王海濤,朱洪.改進的二分法查找[J].計算機工程,2006,32(10):60-62.
[5] 王明,張春熹,伊小素.基于自適應心跳算法的分布式系統故障檢測器[J].北京航空航天大學學報,2013,39(7):952-956.
[6] Mori T,Hirata K,Yamamoto M.Content-oriented probabilistic routing with measured RTT[C]//IEEE International Workshop Technical Committee on Communications Quality and Reliability.IEEE,2016:1-6.
[7] 池文羽.基于Android的人工影響天氣智能終端系統的設計與實現[D].南京信息工程大學,2013:72.
[8] 羅江華.基于MD5與Base64的混合加密算法[J].計算機應用,2012,32(S1):47-49.
[9] Xu Congfu,Chen Yafang,Chiew Kevin.An Approach to Image Spam Filtering Based on Base64 Encoding and N-Gram Feature Extraction[C]//2012 IEEE 24th International Conference on Tools with Artificial Intelligence (2010),2010:171-177.