当前位置:首页 > 物联网 > 智能应用
[导读]嵌入式边缘节点远程运维别让每台设备都开HTTP轮询。合理架构是“边缘Agent轻量采集→MQTT/TLS上送→Java接入服务聚合→Redis存最新状态、时序库存历史→心跳健康状态机判在线/假死/离线→批量命令/配置/OTA下发→WebSocket推大屏”。千级节点用Spring Boot+MQTT+Redis可落地,万级再拆接入集群。


嵌入式边缘节点远程运维别让每台设备都开HTTP轮询。合理架构是“边缘Agent轻量采集→MQTT/TLS上送→Java接入服务聚合→Redis存最新状态、时序库存历史→心跳健康状态机判在线/假死/离线→批量命令/配置/OTA下发→WebSocket推大屏”。千级节点用Spring Boot+MQTT+Redis可落地,万级再拆接入集群。

一、边缘Agent:资源与心跳一起采

Agent跑在ARM Linux/工控机,定周期采CPU、内存、磁盘、进程、网络RTT、业务队列深度,心眺包和业务包分开。用Eclipse Paho:

public class EdgeAgent {

   MqttClient client;

   ScheduledExecutorService sch = Executors.newScheduledThreadPool(2);

   public void start(String broker, String id, String token) throws MqttException {

       client = new MqttClient(broker, id, new MemoryPersistence());

       MqttConnectOptions o = new MqttConnectOptions();

       o.setUserName(id); o.setPassword(token.toCharArray());

       o.setAutomaticReconnect(true); o.setConnectionTimeout(5);

       o.setWill("edge/"+id+"/status", "offline".getBytes(), 1, true);

       client.connect(o);

       client.subscribe("edge/"+id+"/cmd", 1);

       sch.scheduleAtFixedRate(this::reportHealth, 0, 30, TimeUnit.SECONDS);

   }

   void reportHealth() {

       Runtime r = Runtime.getRuntime();

       Health h = new Health();

       h.cpu = OshiHelper.cpuPercent();                 // OSHI/Proc采集

       h.memUsed = r.totalMemory()-r.freeMemory();

       h.memTotal = r.totalMemory();

       h.ts = System.currentTimeMillis();

       h.aliveTasks = LocalTaskRegistry.runningCount(); // 业务线程/任务数

       try { client.publish("edge/"+h.id+"/health", JsonUtil.toJson(h).getBytes(), 1, false); }

       catch (Exception e) { LocalBuffer.store(h); }     // 断网落本地,重连补传

   }

}

心跳不能只看TCP Keepalive:应用死锁、MQTT连着但业务停摆,平台仍会误判在线。健康模型用三层——链路心跳、任务心跳、数据新鲜度。

二、Java接入:聚合、去重、状态机

平台订阅edge/+/health、edge/+/telemetry,异步写Redis最新值,异步落InfluxDB/MySQL历史;同一条消息按deviceId+ts做幂等,QoS1重投不重复入库。

@Component

public class HealthConsumer {

   @Autowired StringRedisTemplate redis;

   @Autowired AlertService alert;

   public void onHealth(Health h) {

       redis.opsForValue().set("edge:health:"+h.id, JsonUtil.toJson(h), 5, TimeUnit.MINUTES);

       DeviceState s = StateCache.get(h.id);

       if (s == null) s = new DeviceState(h.id);

       s.lastHealthTs = h.ts;

       s.cpu = h.cpu; s.mem = h.memUsed*100/h.memTotal;

       s.taskAlive = h.aliveTasks;

       s.link = "UP";

       if (h.cpu > 95 && s.cpuHighCount++ > 3) alert.fire(h.id, "CPU持续过高");

       if (h.aliveTasks == 0 && s.expectedTasks > 0) alert.fire(h.id, "业务任务假死");

       StateCache.put(s);

   }

}

离线判定用“心跳周期×容错次数”,例如30s一次、连续3次未到判离线,避免抖动误报; 群体同网段/同固件集中离线单独升P0,单台按业务等级升P1/P2。

定时巡检补刀,处理“MQTT连着但健康包不来的假在线”:

@Scheduled(fixedDelay = 30000)

public void sweep() {

   for (DeviceState s : StateCache.all()) {

       long gap = System.currentTimeMillis() - s.lastHealthTs;

       if (gap > 90000) { s.link = "OFFLINE"; alert.fire(s.id, "心跳超时离线"); }

       else if (gap > 45000) { s.link = "DEGRADED"; }

   }

}

三、批量监控与命令下发

批量重启、批量拉配置、批量查版本,用线程池按分组并发,单台失败不影响整体,结果汇总:

public Map<String,String> batchRestart(List<String> ids) {

   Map<String,String> r = new ConcurrentHashMap<>();

   ids.parallelStream().forEach(id->{

       try {

           mqtt.publish("edge/"+id+"/cmd",

               JsonUtil.toJson(new Cmd("restart","trace-"+UUID.randomUUID())).getBytes(),1,false);

           r.put(id,"sent");

       } catch (Exception e) { r.put(id,"ERR:"+e.getMessage()); }

   });

   return r;

}

命令带traceId,设备执行完回edge/{id}/cmd/ack,平台更新状态;超时未回自动重投一次,仍失败转人工。配置/固件走灰度:先1台→同组10%~20%→全量,版本号不匹配不下发,弱网用本地缓存+断点续传,写临时文件rename防断电损坏。

四、大屏与弱网闭环

WebSocket只推状态变更,不轮询:Redis状态变→SimpMessagingTemplate推/topic/edge/{group};前端按设备、站点、固件版本聚合在线率、CPU TOP10、离线分布。

弱网要点:Agent本地有界队列缓存健康/告警,重连后按ts补传关键事件;MQTT持久会话+QoS1,配置用QoS2或“版本号拉取”兜底;TLS/mTLS一机一密,敏感命令服务端留操作审计。 这样千台边缘网关可做到30s级健康可见、分钟级批量处置,假死、离线、配置漂移都能远程收敛。



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭