4. 通信中间件总体架构设计
EAP 设备通信中间件要同时面对三类现实:设备侧协议碎片化(SECS/GEM、Modbus TCP、OPC UA、MQTT、私有 TCP 二进制)、连接规模大且长连接占比高(数千至上万设备会话)、上层 MES/EAP 应用对消息的时延与可靠性要求不一致。因此总体架构不能是“一个网关加一个转发器”,而应按职责切分为六层:接入网关层、协议适配层、会话管理层、消息路由层、数据缓存层、运维管理层。前五层构成数据面,运维管理层构成控制面。下图给出组件图与部署映射关系。
各层职责与技术选型依据
接入网关层负责把物理连接变成受控的 Channel。选型 Netty 而非传统 Servlet 容器的依据是:SECS/GEM 与私有 TCP 都是长连接、二进制帧、需要自定义拆包,Netty 的 ByteToMessageDecoder 与 IdleStateHandler 能直接表达“长度字段 + 粘包处理 + 空闲检测”。部署上按设备数量水平扩展,每实例维持 3000~5000 连接,前面用 LVS 做四层负载,避免七层网关破坏长连接。
协议适配层把异构报文翻译成统一消息模型。关键设计是“一个协议一个 Codec + 一个 PointMapper”,Codec 只做字节与结构体互转,PointMapper 负责把 SECS 的 SVID、Modbus 的寄存器地址、OPC UA 的 NodeId 映射为统一点位编码,例如 EQP01.TEMP.PV。这样新增协议只增加插件,不改路由与缓存。
会话管理层维护设备会话状态机与事务配对。SECS/GEM 的 T3(回复超时)、T5(连接分离超时)、T6(控制事务超时)、T7(未选择超时)必须由本层统一计时,不能散落在业务代码里。事务配对用 SystemBytes 作为键,超时后主动发 S9F7 或触发重连,避免上层收到“永远等不到”的响应。
消息路由层按 deviceId、topic、消息类型做匹配与分发。选型 Kafka 而非纯内存队列的依据是:遥测数据允许秒级延迟但要求可回放,告警要求毫秒级且不丢。因此采用“内存优先级队列 + Kafka 持久化”双通道:告警走内存直投,遥测批量写 Kafka,由消费者按订阅关系分发到 MES/EAP。
数据缓存层解决三类问题:会话与点位最新值用 Redis Hash 缓存并设 TTL;突发流量用 Kafka 削峰;设备断网期间用本地环形缓冲暂存,恢复后按序补传。缓存键设计为 dev:{deviceId}:point:{pointCode},值包含时间戳与质量码,避免上层读到过期数据。
关键配置示例
middleware:
gateway:
port: 5000 # HSMS 端口
worker-threads: 16
max-connections: 8000
session:
t3-timeout-ms: 45000
t5-timeout-ms: 10000
t6-timeout-ms: 5000
t7-timeout-ms: 10000
route:
alert-topic: eap.alert
telemetry-topic: eap.telemetry
batch-size: 500
cache:
redis-ttl-seconds: 300
ring-buffer-size: 10000
判断架构是否落地成功,可观察三个指标:单实例连接数是否稳定在设定水位、T3 超时率是否低于 0.5%、Kafka 消费延迟是否在 2 秒内。若 T3 超时率升高,优先检查会话管理层的计时线程是否被阻塞;若消费延迟升高,优先检查路由层批量参数与缓存层背压策略。