物联网(IoT)系统的本质是"感知-传输-存储-应用"的闭环:通过传感器感知物理世界,经过网络把数据传到云端,存储后再被业务应用消费。看似简单的链路,在工程落地时却涉及设备选型、协议选择、网关配置、平台搭建、安全认证等诸多环节。本文结合赢式科技团队的物联网项目实践,从架构设计到代码实现,系统讲解物联网系统开发的全流程要点。

一、物联网系统整体架构

物联网系统通常采用四层架构:感知层、网络层、平台层、应用层。每一层职责清晰,层间通过标准接口解耦。

┌──────────────────────────────────────────────────┐
│  应用层 (Application)                             │
│  Web看板 / 移动APP / 微信小程序 / 大屏可视化        │
│  - 设备管理、报警推送、报表分析、规则引擎           │
├──────────────────────────────────────────────────┤
│  平台层 (Platform)                                │
│  MQTT Broker(EMQX) / 时序数据库(TDengine/InfluxDB) │
│  / 应用服务(Java/Go) / 设备影子 / 规则引擎         │
├──────────────────────────────────────────────────┤
│  网络层 (Network)                                 │
│  - 边缘网关 / 4G路由器 / NB-IoT基站               │
│  - 协议转换:Modbus/OPC UA → MQTT/HTTP            │
├──────────────────────────────────────────────────┤
│  感知层 (Perception)                              │
│  - 传感器、PLC、仪表、RFID、摄像头                 │
│  - RS485/RS232/CAN/Digital IO 接入                │
└──────────────────────────────────────────────────┘

感知层负责"看得见"物理世界,包括温度、湿度、压力、流量、位置等传感器及PLC、仪表等设备;网络层负责"传得动",把数据从设备送到云端,常用的有有线(以太网、光纤)和无线(4G/5G、LoRa、NB-IoT、WiFi)两种方式;平台层负责"管得住",是整个系统的中枢,承担设备管理、数据存储、规则引擎等核心功能;应用层负责"用得好",把数据变成业务价值。

二、设备接入方案

设备接入是物联网系统的入口,需要根据设备类型、部署环境、传输距离、功耗要求等综合选择。接入方式主要分为有线和无线两大类。

接入方式传输距离带宽功耗部署成本典型场景
RS-485(有线)1.2km低(115kbps)车间仪表、变频器
Ethernet(有线)100m高(1Gbps)PLC、工控设备
WiFi(无线)100m智能家电、办公环境
LoRa(无线)2-15km低(50kbps)极低中(需自建网关)农业监测、智慧园区
NB-IoT(无线)10km+低(20kbps)极低低(运营商基站)智能水表、燃气表
4G/5G(无线)基站覆盖低(流量费)移动设备、视频回传

选型经验:固定部署、有电源供电、对带宽要求高的设备(如PLC、视频监控)优先有线或4G/5G;分布广、电池供电、低频次上报的设备(如水表、环境监测节点)优先NB-IoT或LoRa;办公或家庭场景的智能设备可用WiFi。在赢式科技参与的智慧园区项目中,环境监测节点采用LoRa(自建网关),能耗监测仪表采用RS-485+4G网关(数据量较大)。

三、通信协议选型

物联网通信协议众多,常见包括MQTT、CoAP、HTTP等。协议选择直接影响系统的实时性、可靠性和扩展性。

协议传输层报文大小通信模式实时性适用场景
MQTTTCP极小(2字节固定头)发布订阅高(毫秒级)实时数据上报、命令下发
CoAPUDP请求响应低功耗受限设备
HTTPTCP较大(文本头)请求响应历史数据批量上传
WebSocketTCP双向通信Web端实时推送

3.1 为什么是MQTT

MQTT已成为物联网领域事实上的标准协议,原因在于其设计精巧:基于发布订阅模式,设备与平台解耦;报文极小(最小仅2字节),适合低带宽环境;提供三种QoS等级(0至多一次、1至少一次、2恰好一次),可根据业务场景权衡可靠性与性能;支持遗嘱消息(LWT),设备异常掉线时平台可自动感知。

典型Topic设计示例:/{productId}/{deviceName}/things/property/post(属性上报)、/{productId}/{deviceName}/things/property/set(属性下发)、/{productId}/{deviceName}/things/event/{eventId}(事件上报)。Topic设计要兼顾可读性、扩展性与权限控制。

四、边缘网关选型与配置

边缘网关是连接感知层与平台层的桥梁,承担协议转换、数据缓存、本地计算等职责。选型时需要关注:支持的下行协议(Modbus、OPC UA、CAN等)、上行协议(MQTT、HTTP)、计算资源(CPU、内存、存储)、工作温度范围、电源冗余等。

4.1 硬件选型

常见的边缘网关硬件方案有三类:工业级网关成品(如映翰通InGateway、有人物联网网关)、嵌入式工控机+网关软件(如树莓派+Node-RED)、自研网关(基于Linux SBC)。对于稳定性和售后要求高的项目,建议选择工业级网关成品;对于成本敏感、定制化需求强的项目,可考虑嵌入式方案。

4.2 协议转换配置

以映翰通InGateway为例,配置Modbus RTU转MQTT的流程:在Web管理界面添加Modbus串口子设备→配置采集点位表(地址、数据类型、采集周期)→配置MQTT云端连接(Broker地址、端口、用户名密码、TLS证书)→配置数据上报模板(JSON格式、Topic映射)→启用规则引擎做边缘计算(如滤波、聚合、阈值判断)。配置完成后,网关会按周期采集Modbus数据,封装成JSON上报到MQTT Broker。

4.3 数据缓存策略

当网络中断或云端不可用时,网关需要在本地缓存数据,待恢复后补传。常见策略:循环队列缓存(FIFO,限制条数)+ SQLite持久化(断电不丢)+ 指数退避重传(避免恢复瞬间冲击平台)。缓存上限要根据网关存储容量设置(如最近3天数据),超过上限时旧数据可被丢弃或仅保留聚合后的统计值。

五、云端平台搭建

云端平台是物联网系统的核心,承担设备接入、数据存储、业务处理、应用接口等职责。一个典型的物联网平台技术栈如下:

组件选型职责
MQTT BrokerEMQX / Mosquitto设备接入、消息路由、ACL权限
时序数据库TDengine / InfluxDB海量时序数据高效存储与查询
关系数据库MySQL / PostgreSQL设备元数据、用户、配置信息
缓存Redis设备影子、实时状态、限流
消息队列Kafka / RabbitMQ解耦采集与处理、削峰填谷
应用服务Spring Boot / Go业务逻辑、对外API、规则引擎
可视化Vue + ECharts / Grafana数据看板、报表、告警展示

5.1 MQTT Broker:EMQX

EMQX是开源的分布式MQTT Broker,单节点支持百万级连接,提供丰富的认证方式(用户名密码、JWT、HTTP认证)、ACL规则(基于Topic的发布订阅权限)、规则引擎(SQL语法过滤与转换消息)、桥接与集群功能。生产环境建议至少3节点集群部署,开启TLS加密,配合负载均衡(如Nginx、HAProxy)实现高可用。

5.2 时序数据库:TDengine

物联网数据具有"写多读少、按时间查询、降采样统计"的特点,传统关系数据库难以应对海量时序写入。TDengine是国产开源时序数据库,按"超级表-子表"组织数据,每个设备对应一张子表,写入性能远高于MySQL,原生支持降采样查询(如5分钟聚合、小时聚合)。InfluxDB是另一选择,语法简洁(Flux/InfluxQL),社区生态成熟。

六、数据上云全流程代码示例

下面以一个温度传感器数据上报为例,演示从设备注册到可视化的完整流程。

6.1 设备注册(平台侧)

POST /api/v1/devices
Content-Type: application/json

{
    "productId": "temp-sensor-001",
    "deviceName": "sensor-workshop-A-01",
    "deviceSecret": "a3f8b2c9d1e7...",
    "tags": { "location": "车间A", "owner": "张工" }
}

# 响应
{
    "code": 0,
    "data": {
        "deviceId": "dev-2026-0814-0001",
        "mqttEndpoint": "mqtt://broker.it-ys.com:1883",
        "username": "sensor-workshop-A-01|temp-sensor-001",
        "password": "token-generated-by-platform"
    }
}

6.2 设备数据上报(设备/网关侧,Python示例)

import paho.mqtt.client as mqtt
import json
import time
import random

BROKER = "broker.it-ys.com"
PORT = 1883
USERNAME = "sensor-workshop-A-01|temp-sensor-001"
PASSWORD = "token-generated-by-platform"
DEVICE_NAME = "sensor-workshop-A-01"
PRODUCT_ID = "temp-sensor-001"

client = mqtt.Client(client_id=f"{PRODUCT_ID}_{DEVICE_NAME}")
client.username_pw_set(USERNAME, PASSWORD)

# 遗嘱消息:设备异常掉线时平台自动感知
client.will_set(
    f"/{PRODUCT_ID}/{DEVICE_NAME}/status/offline",
    json.dumps({"timestamp": int(time.time()), "reason": "unexpected"}),
    qos=1
)

def on_connect(client, userdata, flags, rc):
    if rc == 0:
        print("连接成功")
        # 上线通知
        client.publish(
            f"/{PRODUCT_ID}/{DEVICE_NAME}/status/online",
            json.dumps({"timestamp": int(time.time())}),
            qos=1
        )
    else:
        print(f"连接失败,错误码: {rc}")

client.on_connect = on_connect
client.connect(BROKER, PORT, 60)
client.loop_start()

# 周期上报温度数据
while True:
    payload = {
        "id": int(time.time()),
        "version": "1.0",
        "params": {
            "temperature": round(random.uniform(20.0, 35.0), 2),
            "humidity": round(random.uniform(40.0, 70.0), 2)
        },
        "time": int(time.time() * 1000)
    }
    topic = f"/{PRODUCT_ID}/{DEVICE_NAME}/things/property/post"
    client.publish(topic, json.dumps(payload), qos=1)
    print(f"已上报: {payload}")
    time.sleep(10)

6.3 平台接收与存储(Java示例)

@Service
public class DeviceMessageHandler {

    @Autowired
    private TdengineJdbcTemplate tdengine;
    @Autowired
    private RedisTemplate redis;

    @KafkaListener(topics = "device-property-post")
    public void onPropertyPost(String message) {
        PropertyPostDTO dto = JSON.parseObject(message, PropertyPostDTO.class);
        String deviceId = dto.getDeviceId();
        Map params = dto.getParams();
        long ts = dto.getTime();

        // 1. 写入时序数据库 TDengine
        String sql = "INSERT INTO dev_" + deviceId +
                " USING property_data " +
                "TAGS ('" + deviceId + "') " +
                "VALUES (" + ts +
                ", " + params.get("temperature") +
                ", " + params.get("humidity") + ")";
        tdengine.update(sql);

        // 2. 更新设备影子(Redis缓存最新状态)
        String shadowKey = "shadow:" + deviceId;
        redis.opsForHash().putAll(shadowKey, params);
        redis.opsForHash().put(shadowKey, "lastTime", String.valueOf(ts));

        // 3. 规则引擎判断报警
        double temp = ((Number) params.get("temperature")).doubleValue();
        if (temp > 32.0) {
            alarmService.publish(deviceId, "TEMP_HIGH",
                    "温度超过阈值: " + temp + "℃");
        }
    }
}

6.4 可视化查询接口

@GetMapping("/api/devices/{deviceId}/history")
public Result queryHistory(
        @PathVariable String deviceId,
        @RequestParam long startTime,
        @RequestParam long endTime,
        @RequestParam(defaultValue = "1m") String interval) {

    // 按时间窗口降采样查询
    String sql = String.format(
        "SELECT _wstart as ts, AVG(temperature) as temp, AVG(humidity) as hum " +
        "FROM dev_%s " +
        "WHERE ts >= %d AND ts <= %d " +
        "INTERVAL(%s)",
        deviceId, startTime, endTime, interval
    );

    List> rows = tdengine.queryForList(sql);
    return Result.success(rows);
}

前端通过HTTP接口拉取历史数据,结合WebSocket订阅实时推送,即可实现实时看板。一个典型的物联看板包含:设备在线状态、实时数据曲线、报警列表、历史数据报表等模块。

七、物联网系统开发注意事项

7.1 安全认证

物联网设备一旦被恶意接管,可能造成严重后果(如智能门锁被远程打开、工业设备被恶意停机)。安全措施至少包括:设备身份认证(一机一密,避免硬编码密钥)、传输加密(TLS/SSL)、消息签名(防篡改)、平台ACL权限(按Topic限制发布订阅)、密钥定期轮换。生产环境务必关闭明文MQTT端口(1883),只开放TLS端口(8883)。

7.2 断网重连与数据补传

设备或网关侧必须实现断线自动重连,采用指数退避策略(如1s→2s→4s→8s,最大60s),避免在云端短暂不可用时疯狂重连造成"惊群效应"。本地缓存数据时按时间分片,恢复后按顺序补传,补传数据要带原始时间戳,平台侧据此区分实时数据与历史数据。

7.3 设备影子

设备影子(Device Shadow)是平台维护的一份设备状态缓存,解决"设备离线时应用层如何获取/修改状态"的问题。应用层读写影子,平台在设备在线时同步到设备。例如用户在APP上设置空调温度26℃,设备此时离线,平台将期望状态写入影子;设备下次上线时拉取影子,把状态同步为26℃。

7.4 规则引擎

规则引擎让业务人员无需改代码即可配置数据处理规则(如"温度>80℃时推送给维修工")。EMQX自带SQL规则引擎,复杂场景可引入独立规则引擎(如Drools、LiteFlow)。规则引擎要支持热更新、版本回滚,避免规则变更导致系统不可用。

八、赢式科技物联网开发服务介绍

上海赢式信息科技有限公司自2010年成立以来,长期深耕工业物联网与上位机开发领域,累计交付3000+定制化项目,服务覆盖智慧园区、智慧能源、智慧农业、智慧环保、智慧冷链等行业。公司可提供从感知层设备选型、边缘网关配置、云端平台搭建、移动端开发到运维部署的物联网全栈服务,技术栈涵盖EMQX、TDengine、Spring Boot、Vue等主流组件。如果您有物联网系统开发需求,欢迎联系赢式科技获取需求评估与方案报价。