基於 Netty 的幀調度策略,自行實現流量控制及可靠性通訊

「博客搬家」 原地址: 簡書 原發表時間: 2017-07-19

最近正在作一個 Java 後端項目「大規模集羣設備的管理平臺」。使用 Spring 做爲基礎框架,使用 Netty 搭建 TCP 服務器與上萬臺設備組成的集羣通訊,使用基於 JavaFX 的圖形界面應用程序模擬上萬臺設備的行爲,並可對服務器進行壓力測試。git

本項目的基礎實現架構已開源,訪問如下地址獲取: 「GitHub」

Java 服務器中,因爲衆多硬件設備的數據幀處理能力較差可靠性較差,因此在 Netty 模塊中使用的幀調度算法。服務器大規模下發數據幀時,可進行有效的擁塞控制、超時重發,可有效提高集羣設備的可靠性,下降集羣設備的研發難度。github

1. Netty 模塊和大規模集羣設備通訊遇到的問題

  • 硬件設備的幀處理能力較差,單臺設備最大處理能力爲 20 幀/秒,服務器需進行流量控制,避免到達設備的處理極限。
  • 硬件設備的可靠性較差,偶爾會出現丟幀的狀況,故雖使用 TCP 協議,服務器仍需自行保證整個通訊的可靠性。

2. 幀調度策略

因爲這些問題,故自行制定以下幀調度策略,實踐代表,該策略可最大程度上解決以上問題。算法

「注」本部分爲源碼「Netty服務器」部分的解釋說明,需結合源碼進行閱讀。
源碼今後處獲取: 「GitHub」

2.1 服務器發送 Message 指令策略

服務器 ServerTcpMessageHandler 對象首先檢查鏈表雙端隊列「LinkedBlockingDeque」中待發送幀的數量,若數量大於限定數量,則將待執行指令「Message」傳入時間輪進行等待,使之在預訂的時間後執行。後端

服務器發送 Message 指令策略

2.2 Message 指令執行策略

待執行的指令 Message 有兩種:服務器

  • 基本指令:普通幀生成指令,該指令分爲如下 2 種:架構

    • 複合指令:一條指令須要多個 CAN 幀才能完整表示
    • 簡單指令:一條指令生成一個 CAN 幀
  • WebMsgSpecial:包含特殊執行指令,該指令均內含一條普通指令,該指令分爲如下 3 種:框架

    • 廣播發送:發送至一組或多組設備
    • 緊急發送:將生成的 CAN 幀放置在隊列首位,以便優先發送
    • 不設置檢錯重發:該 CAN 幀無回覆,或重複發送該幀易致使設備異常

Netty 通道「WebMsgOutBoundHandler」接收到待執行的指令 Message,根據 Message 指令進行執行,生成 CAN 幀並被 SendableMsg 對象包裹,具體執行策略以下:測試

  • 若爲基本指令:生成相對應的一個或多個 CAN 幀,並添加進入不一樣的 SendableMsg 對象,執行策略設爲非緊急和開啓檢錯重發機制。
  • 若爲 WebMsgSpecial 指令spa

    • 若爲廣播指令:將內含 Message 根據廣播指令生成多條其餘 WebMsgSpecial 指令
    • 若爲其餘指令:生成 CAN 幀和對應的 SendableMsg 對象的同時,將「緊急」和「檢錯重發」標識添加進 SendableMsg 對象

Netty 通道「WebMsgOutBoundHandler」接收到待執行的「執行通道」指令 SendableMsg,根據指令進行執行:.net

1) SendableMsg 指令執行策略

若爲「緊急」指令,將內含的 CAN 幀放置在隊列首位,以便優先發送
若爲「不檢錯重發」指令,在內含的 CAN 幀被髮送後,不執行「檢錯重發」操做
若爲「普通」指令,執行「非緊急」操做和「檢錯重發」操做

檢錯重發操做執行策略

2) 檢錯重發操做執行策略

在隊列中選取首位 SendableMsg 對象,內含 CAN 幀被髮送的同時,CAN 幀的「組號」、「設備號」和「功能位」組成 Key,CAN 幀做爲 Value,添加進 HashMap 中,並在時間輪上設置「檢錯重發」策略,該策略在約定延遲時間後執行,以後在 TCP 通道發送該 CAN 幀。

在約定延遲時間內,Netty 的 InBound 處理通道收到特定 CAN 幀的回覆,則將特定 CAN 幀的「Key, Value」對從 HashMap 中移除。

在約定時間後,執行時間輪「檢錯重發」策略:

  • 檢測 HashMap 中相應 CAN 幀的「Key, Value」對:

    • 若爲空,則服務器收到該 CAN 幀的回覆,該策略終止
    • 若不爲空,則服務器未收到該 CAN 幀的回覆,查看 SendableMsg 對象的執行次數

      • 若次數大於 3 次,Netty 模塊向 Server 模塊發送設備通訊故障 Message,將該設備設爲異常狀態。
      • 若次數小於 3 次,根據 SendableMsg 指令的內含操做從新執行。

3. 參考資料

  1. 本項目的「GitHub」
  2. Netty 源碼解讀之時間輪算法實現-HashedWheelTimer
相關文章
相關標籤/搜索