「博客搬家」 原地址: 简书 原发表时间: 2017-07-19git
最近正在作一个 Java 后端项目「大规模集群设备的管理平台」。使用 Spring 做为基础框架,使用 Netty 搭建 TCP 服务器与上万台设备组成的集群通讯,使用基于 JavaFX 的图形界面应用程序模拟上万台设备的行为,并可对服务器进行压力测试。github
本项目的基础实现架构已开源,访问如下地址获取:「GitHub」算法
Java 服务器中,因为众多硬件设备的数据帧处理能力较差,可靠性较差,因此在 Netty 模块中使用的帧调度算法。服务器大规模下发数据帧时,可进行有效的拥塞控制、超时重发,可有效提高集群设备的可靠性,下降集群设备的研发难度。后端
硬件设备的帧处理能力较差,单台设备最大处理能力为 20 帧/秒,服务器需进行流量控制,避免到达设备的处理极限。服务器
硬件设备的可靠性较差,偶尔会出现丢帧的状况,故虽使用 TCP 协议,服务器仍需自行保证整个通讯的可靠性。架构
因为这些问题,故自行制定以下帧调度策略,实践代表,该策略可最大程度上解决以上问题。框架
**「注」**本部分为源码「Netty服务器」部分的解释说明,需结合源码进行阅读。 源码今后处获取:「GitHub」测试
服务器 ServerTcpMessageHandler 对象首先检查链表双端队列「LinkedBlockingDeque」中待发送帧的数量,若数量大于限定数量,则将待执行指令「Message」传入时间轮进行等待,使之在预订的时间后执行。.net
待执行的指令 Message 有两种:netty
- 基本指令:普通帧生成指令,该指令分为如下 2 种:
- 复合指令:一条指令须要多个 CAN 帧才能完整表示
- 简单指令:一条指令生成一个 CAN 帧
- WebMsgSpecial:包含特殊执行指令,该指令均内含一条普通指令,该指令分为如下 3 种:
- 广播发送:发送至一组或多组设备
- 紧急发送:将生成的 CAN 帧放置在队列首位,以便优先发送
- 不设置检错重发:该 CAN 帧无回复,或重复发送该帧易致使设备异常
Netty 通道「WebMsgOutBoundHandler」接收到待执行的指令 Message,根据 Message 指令进行执行,生成 CAN 帧并被 SendableMsg 对象包裹,具体执行策略以下:
Netty 通道「WebMsgOutBoundHandler」接收到待执行的「执行通道」指令 SendableMsg,根据指令进行执行:
若为「紧急」指令,将内含的 CAN 帧放置在队列首位,以便优先发送 若为「不检错重发」指令,在内含的 CAN 帧被发送后,不执行「检错重发」操做 若为「普通」指令,执行「非紧急」操做和「检错重发」操做
在队列中选取首位 SendableMsg 对象,内含 CAN 帧被发送的同时,CAN 帧的「组号」、「设备号」和「功能位」组成 Key,CAN 帧做为 Value,添加进 HashMap 中,并在时间轮上设置「检错重发」策略,该策略在约定延迟时间后执行,以后在 TCP 通道发送该 CAN 帧。
在约定延迟时间内,Netty 的 InBound 处理通道收到特定 CAN 帧的回复,则将特定 CAN 帧的「Key, Value」对从 HashMap 中移除。
在约定时间后,执行时间轮「检错重发」策略: