长连接心跳问题解决总结
一、長連接的定義與心跳說明
我們在客戶端(手機APP、瀏覽器、電腦客戶端等)去向服務器請求數據交互的時候,一般是通過網絡進行消息的傳輸。其中依據網絡傳輸協議,與服務器建立的連接都是基于TCP/UDP進行。依據這些,我們可以粗略的認為客戶端與服務器建立了能長期進行數據傳輸的網絡通道,這就是長連接。
一般來說,TCP的機制可以為我們提供相對穩定的連接監聽,即當客戶端主動斷開網絡連接的時候,服務器也能及時(5秒以內)收到相關動態。但存在一種情況,當客戶端被動斷開網絡連接的時候,例如網線被拔、路由器瞬間短路燒毀等,TCP的?;疃〞r器往往需要很長時間(一般在30分鐘以上)才能讓服務器知道這條連接已經中斷,往往需要使用長連接的場景都伴隨著大量的高頻度的數據交互,這樣就會對我們的業務邏輯造成影響。
為了解決上述問題,于是就有了名為“心跳“的解決方案。即讓客戶端每隔一定的時間間隔(一般是3秒-10秒不等)向服務器發送一次專門用于標記連接存活的消息,如果幾次時間間隔后服務器仍未接收到該消息,就默認該連接已中斷,從而執行用戶的下線處理。
二、心跳問題解決
筆者這里的模擬場景是游戲連接中的心跳問題解決流程。
基本環境:游戲服務器 + Redis存儲玩家數據
1. 初始思路是服務器維護一個玩家在線連接池,同時在玩家身上設置一個時間戳參數,專門用于接收到的玩家心跳消息后進行刷新,服務器會有一個單獨線程每隔一段時間檢測在線玩家的時間戳,如果超過一定時間就默認斷連,執行玩家下線處理。
問題:玩家在偶然情況下會在剛登陸服務器,即還未來得及發送心跳消息刷新時間戳(時間戳還是上次掉線時的時間戳),就被檢測線程誤傷斷連,導致玩家登陸游戲失敗。具體表現就是玩家偶爾會無法登陸服務器。
2. 優化思路:在玩家連接到服務器的時候就默認執行了一次心跳消息的發送,執行心跳消息時間戳的刷新。
問題:依舊存在玩家在執行心跳消息處理期間被檢測線程誤傷斷連的可能性。
3. 繼續優化:改造檢測線程,在玩家身上增加一個時間戳參數用于記錄玩家登陸時的時間戳。玩家未登錄則對登陸的時間戳檢測,檢測時間間隔較長;玩家登陸后對心跳時間戳進行檢測,檢測時間間隔較短。
問題:玩家數據放置在redis中,出現了因為網絡抖動造成的redis玩家數據獲取失敗,導致斷連情況出現。
4. 接著優化:將兩個記錄時間戳的參數從玩家身上取出,單獨放置在游戲服務器本地進行維護。具體方法是在每個網絡連接上都綁定兩個相關的局部時間戳參數,一個在玩家登陸時進行時間戳更新,一個在玩家登陸后進行心跳時間戳更新。這樣就保證了時間戳參數獲取的可靠性與及時性。
目前的優化只到如此程度,特地寫一篇文章分享一下自己的相關優化思路。如果還有可能存在的問題還請大家留言指出。
總結
以上是生活随笔為你收集整理的长连接心跳问题解决总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设置ListView中的所有Item均不
- 下一篇: windows+python+openc