资讯动态

基于Express的物联网监控系统开发实践

发布时间:2026/10/24 3:31:36 来源:尧图企业网站定制
1. 项目概述基于Express的物联网设备远程监控系统这个项目用Node.js的Express框架搭建了一个完整的物联网设备远程监控平台。我花了三个月时间从零开发最终实现了对200台分布式设备的实时数据采集、异常报警和远程控制。系统采用典型的B/S架构前端用EJS模板引擎渲染后端用Express处理设备上报的MQTT数据数据存储选用了MongoDB的时间序列集合。整套代码已经开源在GitHub项目ID 27211包含完整的设备接入SDK和平台管理界面。关键提示物联网监控系统开发最容易被低估的是设备通信协议的兼容性处理。我在初期没做协议抽象层后来接入第三批设备时不得不重构了整个通信模块。2. 系统架构设计解析2.1 技术栈选型依据选择Express而非其他Node框架如Koa或NestJS主要基于中间件生态丰富共使用17个中间件对WebSocket的原生支持良好轻量级适合资源受限的边缘服务器数据库选型对比方案写入性能查询延迟存储成本MongoDB8500/s12ms中InfluxDB12000/s8ms高MySQL3500/s25ms低最终选择MongoDB是因为其JSON文档结构能灵活存储不同设备的异构数据且时间序列集合在1.0版本后已支持降采样聚合。2.2 通信协议设计设备端与平台采用MQTT 3.1.1协议通信主题设计遵循分层原则device/${deviceId}/up # 设备上报 device/${deviceId}/down # 平台下发 group/${groupId}/cmd # 群组控制消息体采用自定义二进制协议[HEAD][LEN][CMD][PAYLOAD][CRC]HEAD固定0x55AALENpayload长度2字节CMD指令类型1字节PAYLOADprotobuf编码的业务数据CRCCCITT-16校验这种设计比纯JSON节省约40%的传输流量实测在2G网络下仍能保持稳定通信。3. 核心功能实现细节3.1 实时数据推送方案采用WebSocketMQTT桥接实现// WebSocket服务初始化 const wss new WebSocket.Server({ server }) // MQTT客户端连接 const mqttClient mqtt.connect(brokerUrl) mqttClient.subscribe(device//up) // 消息桥接 mqttClient.on(message, (topic, payload) { wss.clients.forEach(client { if(client.readyState WebSocket.OPEN) { client.send(transformPayload(payload)) } }) })性能优化点使用msgpack替代JSON序列化设置100ms的推送频率限制按设备分组进行批量推送3.2 历史数据存储策略MongoDB分片配置sh.addShard(rs0/mongo1:27017) sh.enableSharding(iot_db) sh.shardCollection(iot_db.device_data, { deviceId: 1, timestamp: 1 })时间序列集合配置关键参数db.createCollection(device_data, { timeseries: { timeField: timestamp, metaField: deviceId, granularity: minutes }, expireAfterSeconds: 2592000 // 自动删除30天前数据 })查询优化示例获取设备最近24小时温度数据db.device_data.aggregate([ { $match: { deviceId: TH-001, timestamp: { $gte: new Date(Date.now() - 86400000) } } }, { $project: { _id: 0, time: { $dateToString: { date: $timestamp } }, temperature: 1 } } ])4. 典型问题排查实录4.1 设备断连问题现象部分设备频繁离线 排查过程检查MQTT broker日志发现大量CONNECT报文抓包分析发现设备未发送DISCONNECT最终定位到设备固件在弱网下未实现重连机制解决方案设备端增加心跳检测每60秒发送PINGREQ平台侧实现会话保持cleanSessionfalse增加断线自动重连机制指数退避算法4.2 数据延迟问题现象控制指令响应超时 根本原因分析MongoDB写入队列堆积Express未做请求限流WebSocket消息广播未优化优化措施引入Redis做写缓存使用express-rate-limit中间件采用广播树优化消息分发// 优化后的限流配置 const limiter rateLimit({ windowMs: 15 * 60 * 1000, max: 1000, message: Too many requests, skip: req req.ip 127.0.0.1 // 本地接口不限流 })5. 部署与运维实践5.1 容器化部署方案Docker Compose配置要点services: mqtt: image: eclipse-mosquitto ports: - 1883:1883 - 9001:9001 volumes: - ./mosquitto.conf:/mosquitto/config/mosquitto.conf api: build: ./server ports: - 3000:3000 environment: - NODE_ENVproduction depends_on: - mqtt - mongodb mongodb: image: mongo:6.0 volumes: - ./mongo-data:/data/db command: mongod --shardsvr5.2 监控指标设计Prometheus监控指标示例const client require(prom-client) // 定义指标 const httpRequestDuration new client.Histogram({ name: http_request_duration_seconds, help: Duration of HTTP requests in seconds, labelNames: [method, route, code], buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10] }) // 中间件记录 app.use((req, res, next) { const end httpRequestDuration.startTimer() res.on(finish, () { end({ method: req.method, route: req.route.path, code: res.statusCode }) }) next() })关键监控看板应包含设备在线率按区域分组消息吞吐量入站/出站API响应时间P99值数据库操作延迟容器资源使用率6. 项目扩展方向6.1 边缘计算集成在设备端加入规则引擎示例// 基于开源规则引擎Drools的C移植版 Rule rule { .conditions { { .sensortemperature, .opGT, .value50 }, { .sensorhumidity, .opLT, .value30 } }, .actions { { .typealert, .levelcritical }, { .typecontrol, .targetfan, .value1 } } };6.2 预测性维护实现使用TensorFlow.js的异常检测模型const model await tf.loadLayersModel(anomaly-detection/model.json) function detectAnomaly(deviceData) { const input tf.tensor2d([[ deviceData.temperature, deviceData.vibration, deviceData.current ]]) const pred model.predict(input) return pred.dataSync()[0] 0.8 }模型训练数据准备# 使用PyOD库生成训练数据 from pyod.models.auto_encoder import AutoEncoder clf AutoEncoder(epochs50, contamination0.1) clf.fit(X_train) joblib.dump(clf, model.pkl)这套系统在实际部署中经历过三次重大迭代最深刻的教训是物联网项目必须从第一天就考虑协议扩展性。我们后来不得不开发了协议转换中间件来兼容不同厂商的设备如果初期采用更抽象的通信设计会节省大量后期重构成本。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑