DolphinDB MQTT协议接入:工业设备数据采集

目录

    • 摘要
    • 一、MQTT协议概述
      • [1.1 什么是MQTT](#1.1 什么是MQTT)
      • [1.2 MQTT特点](#1.2 MQTT特点)
      • [1.3 MQTT在工业物联网中的应用](#1.3 MQTT在工业物联网中的应用)
    • [二、DolphinDB MQTT插件](#二、DolphinDB MQTT插件)
      • [2.1 插件安装](#2.1 插件安装)
      • [2.2 插件配置](#2.2 插件配置)
    • 三、MQTT连接管理
      • [3.1 创建连接](#3.1 创建连接)
      • [3.2 连接参数](#3.2 连接参数)
      • [3.3 连接状态监控](#3.3 连接状态监控)
    • 四、主题订阅
      • [4.1 订阅主题](#4.1 订阅主题)
      • [4.2 取消订阅](#4.2 取消订阅)
      • [4.3 QoS级别](#4.3 QoS级别)
    • 五、数据解析
      • [5.1 JSON数据解析](#5.1 JSON数据解析)
      • [5.2 自定义格式解析](#5.2 自定义格式解析)
      • [5.3 二进制数据解析](#5.3 二进制数据解析)
    • 六、数据写入
      • [6.1 实时写入流表](#6.1 实时写入流表)
      • [6.2 写入分布式表](#6.2 写入分布式表)
      • [6.3 批量写入优化](#6.3 批量写入优化)
    • 七、高可用部署
      • [7.1 断线重连](#7.1 断线重连)
      • [7.2 心跳检测](#7.2 心跳检测)
      • [7.3 数据缓冲](#7.3 数据缓冲)
    • 八、实战案例
      • [8.1 工业设备数据采集系统](#8.1 工业设备数据采集系统)
    • 九、总结
    • 参考资料

摘要

本文深入讲解DolphinDB MQTT协议接入技术。从MQTT协议原理到插件配置,从主题订阅到数据解析,从实时写入到高可用部署,全面介绍MQTT数据采集的核心方法。通过丰富的代码示例,帮助读者掌握工业设备数据采集的核心技能。


一、MQTT协议概述

1.1 什么是MQTT

MQTT(Message Queuing Telemetry Transport)是轻量级消息传输协议:
#mermaid-svg-hRuG5DkOMmH42U5b{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-hRuG5DkOMmH42U5b .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-hRuG5DkOMmH42U5b .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-hRuG5DkOMmH42U5b .error-icon{fill:#552222;}#mermaid-svg-hRuG5DkOMmH42U5b .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hRuG5DkOMmH42U5b .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-hRuG5DkOMmH42U5b .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hRuG5DkOMmH42U5b .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hRuG5DkOMmH42U5b .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-hRuG5DkOMmH42U5b .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hRuG5DkOMmH42U5b .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hRuG5DkOMmH42U5b .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hRuG5DkOMmH42U5b .marker.cross{stroke:#333333;}#mermaid-svg-hRuG5DkOMmH42U5b svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hRuG5DkOMmH42U5b p{margin:0;}#mermaid-svg-hRuG5DkOMmH42U5b .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-hRuG5DkOMmH42U5b .cluster-label text{fill:#333;}#mermaid-svg-hRuG5DkOMmH42U5b .cluster-label span{color:#333;}#mermaid-svg-hRuG5DkOMmH42U5b .cluster-label span p{background-color:transparent;}#mermaid-svg-hRuG5DkOMmH42U5b .label text,#mermaid-svg-hRuG5DkOMmH42U5b span{fill:#333;color:#333;}#mermaid-svg-hRuG5DkOMmH42U5b .node rect,#mermaid-svg-hRuG5DkOMmH42U5b .node circle,#mermaid-svg-hRuG5DkOMmH42U5b .node ellipse,#mermaid-svg-hRuG5DkOMmH42U5b .node polygon,#mermaid-svg-hRuG5DkOMmH42U5b .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hRuG5DkOMmH42U5b .rough-node .label text,#mermaid-svg-hRuG5DkOMmH42U5b .node .label text,#mermaid-svg-hRuG5DkOMmH42U5b .image-shape .label,#mermaid-svg-hRuG5DkOMmH42U5b .icon-shape .label{text-anchor:middle;}#mermaid-svg-hRuG5DkOMmH42U5b .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-hRuG5DkOMmH42U5b .rough-node .label,#mermaid-svg-hRuG5DkOMmH42U5b .node .label,#mermaid-svg-hRuG5DkOMmH42U5b .image-shape .label,#mermaid-svg-hRuG5DkOMmH42U5b .icon-shape .label{text-align:center;}#mermaid-svg-hRuG5DkOMmH42U5b .node.clickable{cursor:pointer;}#mermaid-svg-hRuG5DkOMmH42U5b .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-hRuG5DkOMmH42U5b .arrowheadPath{fill:#333333;}#mermaid-svg-hRuG5DkOMmH42U5b .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hRuG5DkOMmH42U5b .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hRuG5DkOMmH42U5b .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hRuG5DkOMmH42U5b .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-hRuG5DkOMmH42U5b .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hRuG5DkOMmH42U5b .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-hRuG5DkOMmH42U5b .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hRuG5DkOMmH42U5b .cluster text{fill:#333;}#mermaid-svg-hRuG5DkOMmH42U5b .cluster span{color:#333;}#mermaid-svg-hRuG5DkOMmH42U5b div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hRuG5DkOMmH42U5b .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-hRuG5DkOMmH42U5b rect.text{fill:none;stroke-width:0;}#mermaid-svg-hRuG5DkOMmH42U5b .icon-shape,#mermaid-svg-hRuG5DkOMmH42U5b .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hRuG5DkOMmH42U5b .icon-shape p,#mermaid-svg-hRuG5DkOMmH42U5b .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-hRuG5DkOMmH42U5b .icon-shape .label rect,#mermaid-svg-hRuG5DkOMmH42U5b .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hRuG5DkOMmH42U5b .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-hRuG5DkOMmH42U5b .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-hRuG5DkOMmH42U5b :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} MQTT架构
设备/传感器
MQTT Broker
设备/传感器
设备/传感器
订阅者1
订阅者2
DolphinDB

1.2 MQTT特点

特点 说明
轻量级 协议简单,开销小
发布订阅 一对多通信
QoS级别 消息质量保证
持久会话 断线重连

1.3 MQTT在工业物联网中的应用

场景 说明
设备数据采集 传感器数据上报
远程控制 设备指令下发
状态监控 设备状态推送
告警通知 异常告警推送

二、DolphinDB MQTT插件

2.1 插件安装

python 复制代码
// 检查插件是否已加载
getLoadedPlugins()

// 加载MQTT插件
loadPlugin("mqtt")

// 查看插件函数
mqtt::getPluginFunctions()

2.2 插件配置

python 复制代码
// MQTT连接配置
config = dict(STRING, ANY, [
    ["host", "localhost"],
    ["port", 1883],
    ["clientId", "dolphindb_client"],
    ["username", "admin"],
    ["password", "password"],
    ["keepAlive", 60],
    ["cleanSession", true]
])

三、MQTT连接管理

3.1 创建连接

python 复制代码
// 创建MQTT连接
conn = mqtt::connect("localhost", 1883, "dolphindb_client")

// 查看连接状态
mqtt::getStatus(conn)

// 断开连接
mqtt::disconnect(conn)

3.2 连接参数

python 复制代码
// 完整连接参数
conn = mqtt::connect(
    "localhost",           // broker地址
    1883,                  // 端口
    "dolphindb_client",    // 客户端ID
    "admin",               // 用户名
    "password",            // 密码
    60,                    // keepAlive时间(秒)
    true                   // cleanSession
)

3.3 连接状态监控

python 复制代码
// 监控连接状态
def monitorConnection(conn) {
    status = mqtt::getStatus(conn)
    if (status == "connected") {
        print("MQTT连接正常")
    } else {
        print("MQTT连接异常: " + status)
    }
}

monitorConnection(conn)

四、主题订阅

4.1 订阅主题

python 复制代码
// 创建流表接收数据
share streamTable(1:0, 
    `device_id`timestamp`temperature`humidity,
    [SYMBOL, TIMESTAMP, DOUBLE, DOUBLE]) as mqtt_stream

// 订阅MQTT主题
mqtt::subscribe(conn, "sensor/data", mqtt_stream)

// 订阅多个主题
mqtt::subscribe(conn, "sensor/temperature", temp_stream)
mqtt::subscribe(conn, "sensor/humidity", humid_stream)

// 订阅通配符主题
mqtt::subscribe(conn, "sensor/+/data", mqtt_stream)  // + 单级通配符
mqtt::subscribe(conn, "sensor/#", mqtt_stream)        // # 多级通配符

4.2 取消订阅

python 复制代码
// 取消订阅
mqtt::unsubscribe(conn, "sensor/data")

// 取消所有订阅
mqtt::unsubscribeAll(conn)

4.3 QoS级别

python 复制代码
// QoS级别说明
// QoS 0: 最多一次,可能丢失
// QoS 1: 至少一次,可能重复
// QoS 2: 恰好一次,保证送达

// 订阅时指定QoS
mqtt::subscribe(conn, "sensor/data", mqtt_stream, 1)  // QoS 1

五、数据解析

5.1 JSON数据解析

python 复制代码
// 创建JSON解析流表
share streamTable(1:0, 
    `device_id`timestamp`temperature`humidity,
    [SYMBOL, TIMESTAMP, DOUBLE, DOUBLE]) as json_stream

// JSON解析函数
def parseJsonData(jsonStr) {
    data = parseJson(jsonStr)
    return table(
        data.device_id as device_id,
        data.timestamp as timestamp,
        data.temperature as temperature,
        data.humidity as humidity
    )
}

// 订阅并解析JSON
mqtt::subscribe(conn, "sensor/json", json_stream, 
    def(msg) {
        parseJsonData(msg)
    })

5.2 自定义格式解析

python 复制代码
// 自定义格式:逗号分隔
// 格式:device_id,timestamp,temperature,humidity

def parseCsvData(csvStr) {
    parts = split(csvStr, ",")
    return table(
        parts[0] as device_id,
        timestamp(parts[1]) as timestamp,
        double(parts[2]) as temperature,
        double(parts[3]) as humidity
    )
}

// 订阅并解析
mqtt::subscribe(conn, "sensor/csv", csv_stream, parseCsvData)

5.3 二进制数据解析

python 复制代码
// 二进制数据解析
def parseBinaryData(binaryData) {
    // 假设二进制格式:
    // 前4字节:device_id (int32)
    // 后8字节:temperature (double)
    // 后8字节:humidity (double)
    
    deviceId = parseInt32(binaryData, 0)
    temperature = parseDouble(binaryData, 4)
    humidity = parseDouble(binaryData, 12)
    
    return table(
        deviceId as device_id,
        now() as timestamp,
        temperature as temperature,
        humidity as humidity
    )
}

六、数据写入

6.1 实时写入流表

python 复制代码
// 创建流表
share streamTable(100000:0, 
    `device_id`timestamp`temperature`humidity,
    [SYMBOL, TIMESTAMP, DOUBLE, DOUBLE]) as sensor_stream

// 启用持久化
enableTablePersistence(sensor_stream, true, true, 1000000)

// 订阅MQTT写入流表
mqtt::subscribe(conn, "sensor/data", sensor_stream)

6.2 写入分布式表

python 复制代码
// 创建分布式表
db = database("dfs://mqtt_db", VALUE, 1..1000)
schema = table(1:0, `device_id`timestamp`temperature`humidity,
               [SYMBOL, TIMESTAMP, DOUBLE, DOUBLE])
db.createPartitionedTable(schema, `sensor_data, `device_id)

// 创建流表
share streamTable(100000:0, 
    `device_id`timestamp`temperature`humidity,
    [SYMBOL, TIMESTAMP, DOUBLE, DOUBLE]) as mqtt_stream

// 订阅流表写入分布式表
subscribeTable(, "mqtt_stream", "persist", -1,
    def(msg) {
        loadTable("dfs://mqtt_db", "sensor_data").append!(msg)
    }, 10000, 5000)

// 订阅MQTT
mqtt::subscribe(conn, "sensor/data", mqtt_stream)

6.3 批量写入优化

python 复制代码
// 批量写入配置
// batchSize: 批量大小
// throttle: 节流时间(毫秒)

subscribeTable(, "mqtt_stream", "batch_persist", -1,
    def(msg) {
        loadTable("dfs://mqtt_db", "sensor_data").append!(msg)
    }, 
    10000,   // batchSize: 10000条
    5000)    // throttle: 5秒

七、高可用部署

7.1 断线重连

python 复制代码
// 断线重连配置
def connectWithRetry(host, port, clientId, maxRetries = 5) {
    retries = 0
    while (retries < maxRetries) {
        try {
            conn = mqtt::connect(host, port, clientId)
            print("MQTT连接成功")
            return conn
        } catch (ex) {
            retries += 1
            print("连接失败,重试 " + string(retries) + "/" + string(maxRetries))
            sleep(5000)  // 等待5秒重试
        }
    }
    throw "MQTT连接失败"
}

// 使用
conn = connectWithRetry("localhost", 1883, "dolphindb_client")

7.2 心跳检测

python 复制代码
// 心跳检测函数
def heartbeat(conn, interval = 30) {
    while (true) {
        status = mqtt::getStatus(conn)
        if (status != "connected") {
            print("连接断开,尝试重连...")
            // 重连逻辑
        }
        sleep(interval * 1000)
    }
}

// 启动心跳(异步)
submitJob("mqtt_heartbeat", "MQTT心跳", def() { heartbeat(conn) })

7.3 数据缓冲

python 复制代码
// 数据缓冲:断线时缓存数据
share table(100000:0,
    `device_id`timestamp`temperature`humidity,
    [SYMBOL, TIMESTAMP, DOUBLE, DOUBLE]) as buffer_table

// 写入时先写缓冲
def writeToBuffer(data) {
    buffer_table.append!(data)
}

// 定时从缓冲写入分布式表
def flushBuffer() {
    data = select * from buffer_table
    if (data.rows() > 0) {
        loadTable("dfs://mqtt_db", "sensor_data").append!(data)
        truncate(buffer_table)
    }
}

// 定时任务
scheduleJob("flush_buffer", "刷新缓冲", flushBuffer,
            00:01, 2024.01.01, 2030.12.31, 'D')

八、实战案例

8.1 工业设备数据采集系统

python 复制代码
// ========== 工业设备数据采集系统 ==========

// 1. 创建分布式表
db = database("dfs://iot_mqtt_db", VALUE, 1..1000)
schema = table(1:0, 
    `device_id`timestamp`temperature`humidity`pressure`vibration,
    [SYMBOL, TIMESTAMP, DOUBLE, DOUBLE, DOUBLE, DOUBLE])
db.createPartitionedTable(schema, `device_data, `device_id)

// 2. 创建流表
share streamTable(100000:0, 
    `device_id`timestamp`temperature`humidity`pressure`vibration,
    [SYMBOL, TIMESTAMP, DOUBLE, DOUBLE, DOUBLE, DOUBLE]) as mqtt_stream

// 3. 启用持久化
enableTablePersistence(mqtt_stream, true, true, 1000000)

// 4. 订阅流表写入分布式表
subscribeTable(, "mqtt_stream", "persist", -1,
    def(msg) {
        loadTable("dfs://iot_mqtt_db", "device_data").append!(msg)
    }, 10000, 5000)

// 5. 连接MQTT
conn = mqtt::connect("mqtt-broker.local", 1883, "dolphindb_iot")

// 6. 订阅主题
mqtt::subscribe(conn, "factory/+/sensor", mqtt_stream)

// 7. 监控函数
def monitorMqtt() {
    print("=== MQTT监控 ===")
    print("连接状态: " + mqtt::getStatus(conn))
    print("流表行数: " + string(exec count(*) from mqtt_stream))
    
    t = loadTable("dfs://iot_mqtt_db", "device_data")
    print("分布式表行数: " + string(exec count(*) from t))
}

monitorMqtt()

print("工业设备数据采集系统启动完成")

九、总结

本文详细介绍了DolphinDB MQTT协议接入:

  1. MQTT协议:轻量级、发布订阅、QoS级别
  2. 插件配置:安装、加载、配置
  3. 连接管理:创建连接、状态监控
  4. 主题订阅:订阅主题、QoS配置
  5. 数据解析:JSON解析、自定义格式、二进制解析
  6. 数据写入:流表写入、分布式表写入、批量优化
  7. 高可用:断线重连、心跳检测、数据缓冲

思考题

  1. MQTT协议有什么优势?
  2. 如何设计高可用的MQTT数据采集系统?
  3. 如何处理MQTT消息丢失问题?

参考资料


相关推荐
九硕智慧建筑一体化厂家3 小时前
数字化管控落地,直流照明构筑安全照明体系
运维·人工智能·笔记·安全·智慧城市
刘某的Cloud4 小时前
ceph osd 导入导出 rbd volume 卷
linux·运维·ceph·volume
神奇霸王龙6 小时前
Agent 准入门控屠夫:5 旗舰 4 维度评估
linux·运维·数据库·ai·ai作画·agent·ai编程
cfm_29146 小时前
基于Binlog实现不停机数据库平滑迁移技术
运维·数据库·架构
迪康Defender7 小时前
AI 重构终端安全运营:智能分析中枢 AI Insight 模块架构与落地场景深度解析
运维·网络·人工智能·其他·安全·重构·架构
HiDev_8 小时前
【非标自动化】2、认识元器件(固态继电器)
运维·自动化
明达智控技术8 小时前
国产 PLC 落地立库自动化,MC5000边缘智能控制器破局
运维·自动化
小绫网络安全9 小时前
Kali Linux渗透测试入门教程:从零搭建到实战攻防
linux·运维·服务器
allforgood9 小时前
控制启动过程
linux·运维·服务器
西安景驰电子9 小时前
《PTP精确时间协议系列》第一篇:从原理到应用,全面解读IEEE 1588
linux·运维·服务器·开发语言·网络·windows·php