「博客搬家」 原地址: 簡書 原發表時間: 2017-07-19
最近正在作一個 Java 後端項目「大規模集羣設備的管理平臺」。使用 Spring 做爲基礎框架,使用 Netty 搭建 TCP 服務器與上萬臺設備組成的集羣通訊,使用基於 JavaFX 的圖形界面應用程序模擬上萬臺設備的行爲,並可對服務器進行壓力測試。git
本項目的基礎實現架構已開源,訪問如下地址獲取: 「GitHub」
Java 服務器中,因爲衆多硬件設備的數據幀處理能力較差,可靠性較差,因此在 Netty 模塊中使用的幀調度算法。服務器大規模下發數據幀時,可進行有效的擁塞控制、超時重發,可有效提高集羣設備的可靠性,下降集羣設備的研發難度。github
因爲這些問題,故自行制定以下幀調度策略,實踐代表,該策略可最大程度上解決以上問題。算法
「注」本部分爲源碼「Netty服務器」部分的解釋說明,需結合源碼進行閱讀。
源碼今後處獲取: 「GitHub」
服務器 ServerTcpMessageHandler 對象首先檢查鏈表雙端隊列「LinkedBlockingDeque」中待發送幀的數量,若數量大於限定數量,則將待執行指令「Message」傳入時間輪進行等待,使之在預訂的時間後執行。後端
待執行的指令 Message 有兩種:服務器
基本指令:普通幀生成指令,該指令分爲如下 2 種:架構
- 複合指令:一條指令須要多個 CAN 幀才能完整表示
- 簡單指令:一條指令生成一個 CAN 幀
WebMsgSpecial:包含特殊執行指令,該指令均內含一條普通指令,該指令分爲如下 3 種:框架
- 廣播發送:發送至一組或多組設備
- 緊急發送:將生成的 CAN 幀放置在隊列首位,以便優先發送
- 不設置檢錯重發:該 CAN 幀無回覆,或重複發送該幀易致使設備異常
Netty 通道「WebMsgOutBoundHandler」接收到待執行的指令 Message,根據 Message 指令進行執行,生成 CAN 幀並被 SendableMsg 對象包裹,具體執行策略以下:測試
若爲 WebMsgSpecial 指令spa
Netty 通道「WebMsgOutBoundHandler」接收到待執行的「執行通道」指令 SendableMsg,根據指令進行執行:.net
若爲「緊急」指令,將內含的 CAN 幀放置在隊列首位,以便優先發送
若爲「不檢錯重發」指令,在內含的 CAN 幀被髮送後,不執行「檢錯重發」操做
若爲「普通」指令,執行「非緊急」操做和「檢錯重發」操做
在隊列中選取首位 SendableMsg 對象,內含 CAN 幀被髮送的同時,CAN 幀的「組號」、「設備號」和「功能位」組成 Key,CAN 幀做爲 Value,添加進 HashMap 中,並在時間輪上設置「檢錯重發」策略,該策略在約定延遲時間後執行,以後在 TCP 通道發送該 CAN 幀。
在約定延遲時間內,Netty 的 InBound 處理通道收到特定 CAN 幀的回覆,則將特定 CAN 幀的「Key, Value」對從 HashMap 中移除。
在約定時間後,執行時間輪「檢錯重發」策略:
檢測 HashMap 中相應 CAN 幀的「Key, Value」對:
若不爲空,則服務器未收到該 CAN 幀的回覆,查看 SendableMsg 對象的執行次數