资讯动态

本地部署物联网平台全攻略:从MQTT到InfluxDB与大模型增强

发布时间:2026/9/24 22:53:05 来源:尧图企业网站定制
上个月帮一个做注塑机车间改造的客户搭了一套本地部署的物联网平台整个过程踩了不少坑也攒了不少可以直接复用的经验。今天把思路、选型逻辑和能落地的细节整理出来给正准备做本地部署物联网平台的朋友一个参考。先说清楚一点我这里说的“本地部署的物联网平台”不是随便装个开源软件跑起来就完事而是指设备数据采集、传输、存储、可视化、告警、甚至智能分析这一整套链路全部跑在内网环境里不依赖公有云。再加上今年本地部署大模型的热度这么高Ollama、DeepSeek、Dify、RAGFlow这些关键词被反复提起物联网平台本地部署之后再把大模型能力接进去让设备数据自己“开口说话”其实是当前性价比极高的一个演进方向。这篇文章会从需求拆解讲到具体部署代码和命令都会给全。1. 项目思路拆解本地部署物联网平台到底在解决什么问题1.1 哪些场景必须放弃公有云选择本地部署很多人一听物联网平台第一反应是阿里云IoT、AWS IoT Core这类托管服务。的确公有云平台省事按量付费设备接入SDK也齐全。但实际项目里有一批场景是打死都不能上公有云的。我这次碰到的注塑机车间项目就非常典型。客户工厂里的注塑机本身通过PLC控制设备数据涉及模具温度、射胶压力、锁模力、成型周期这些工艺参数。这些数据对企业来说是核心工艺资产老板明确要求数据不能出内网。如果上公有云哪怕只是把设备数据转发到云端做展示客户心里那道坎也过不去。这不是技术问题是信任问题和数据归属问题。类似的场景还有不少工厂车间设备联网设备数据是生产现场的核心资产很多企业在数字化改造的招标文件里直接写明“数据本地存储不得上传至公有云”这种情况下只能做本地部署。园区能耗监控电表、水表、气表数据要接入统一的能源管理平台但园区管理方希望数据完全可控并且不希望每个月为设备接入量支付云平台费用。教学实训环境物联网仿真实训平台里学生需要反复做设备接入、数据采集、规则引擎配置、可视化组态这些实验如果依赖云端网络一抖动实验就断了。本地部署的物联网平台可以无限创建实验环境随便折腾都不会有额外成本。边缘机房、农业大棚、冷链仓库很多这类环境根本没有稳定的公网连接或者带宽非常有限。一个完全跑在本地的小型物联网平台可以把网关、MQTT Broker、规则引擎、告警通知全部放在一台小主机上。这里有个很现实的问题公有云平台按设备数、消息数、数据存储量计费一年下来一台设备的成本看着不高但几百上千台设备再加上长期存储和API调用费用相当可观。本地部署是一次性投入硬件到位后后面新增设备基本没有边际成本。这也是很多中小型项目最终选择本地部署的核心原因。1.2 本地部署的物联网平台整体架构怎么搭明确了要本地部署接下来就是架构设计。物联网平台虽然叫“平台”但绝对不是一个大而全的软件而是一组组件组合起来形成的整体能力。我习惯把整个链路拆成五层层级职责常用开源组件部署方式采集层对接设备协议采集传感器/PLC数据Node-RED、各种边缘网关Docker容器或物理网关传输层设备消息的接入与转发EMQX、Mosquitto、VerneMQDocker容器存储层时序数据、设备元数据、告警记录InfluxDB、TimescaleDB、MySQLDocker容器应用层设备管理、可视化看板、告警通知ThingsBoard、Grafana、Node-REDDocker容器AI增强层设备数据智能分析、知识库问答Ollama、Dify、RAGFlowDocker容器这套架构的好处是每一层都可以单独替换。比如你不想用EMQX传输层换成Mosquitto也能跑你不想用Grafana做可视化换ThingsBoard也行。每层之间通过标准协议通信——采集层到传输层走MQTT传输层到存储层靠规则引擎写入时序数据库应用层通过HTTP/API读取数据。这样哪怕以后某个组件不再维护替换成本也很低。选型的核心原则其实就几条开源优先、社区活跃、本地部署方便、对硬件要求不能太苛刻。容器化是必须的Docker Compose管理一组容器比手工安装一堆依赖要省心太多。我见过有人非要在裸机上装EMQX、InfluxDB、Grafana结果依赖冲突搞了一整天最后老老实实回到Docker Compose。能用容器解决的问题不要自己编译。2. 核心组件选型MQTT Broker、时序数据库与可视化工具的取舍2.1 MQTT Broker首选EMQX的逻辑物联网设备接入最常用的协议是MQTT因为它基于发布/订阅模型非常适合大量设备频繁上报小数据量的场景。而MQTT Broker就是整个平台的“消息中枢”所有设备消息都要经过它转发它的稳定性直接决定了平台的命脉。我一开始考虑过Mosquitto毕竟体积小、部署简单一个几十MB的容器就能跑。但实际用下来发现Mosquitto在功能上偏“裸”——它只提供最基础的MQTT消息转发设备管理、规则引擎、数据集成这些能力全都没有。如果只是接几个传感器玩玩够用但要做一个正经的平台后面还是要补一堆东西。EMQX就完全是另一回事了。它本身是用Erlang写的天生适合高并发连接官方标称单节点可以支撑百万级连接。我们实际项目里几十台设备对它来说就是洒洒水。更关键的是EMQX内置了规则引擎可以直接把MQTT消息通过SQL表达式处理后转发到InfluxDB、MySQL、Kafka等数据源省掉了自己写桥接程序的麻烦。Dashboard也做得不错设备连接数、消息量、订阅关系一眼就能看明白。版本上我推荐直接用5.x。4.x虽然经典但配置方式和插件机制跟5.x差异很大网上搜到的很多教程都是老版本照抄容易踩坑。5.x把认证、权限、规则引擎都整合到了Dashboard里操作图形化配置对新手友好得多。2.2 数据不能进MySQL时序数据库的选型细节设备数据第一特征是“时间戳密集”而且几乎只追加、不修改。这种数据形态如果硬塞进MySQL很快会遇到两个问题一是写入性能设备越多每秒INSERT的并发越高关系型数据库要处理索引、事务很容易成为瓶颈二是查询效率你想看“最近一小时每台设备的平均温度”SQL里要写一堆GROUP BY和日期函数数据量大之后慢得让人抓狂。时序数据库就是专门为这种场景设计的。它把时间戳作为主索引按时间分区存储数据压缩率极高还自带按时间聚合查询的能力。我这次用的是InfluxDB 2.x。选择它的原因是有官方Docker镜像环境变量支持自动初始化部署极其省事自带数据看板和告警规则小项目甚至可以不开GrafanaFlux查询语言功能强大窗口聚合、降采样、异常检测都能写2.x版本把权限、组织、桶Bucket的概念整合得很清晰比1.x的数据库/保留策略模式简单不少。如果数据量特别大或者你对SQL生态更熟可以考虑TimescaleDB。它是PostgreSQL的扩展写的是标准SQL迁移平滑很多用过传统数据库的人上手很快。但TimescaleDB对硬件要求比InfluxDB高一点而且规则引擎集成到InfluxDB更顺滑所以我个人还是推荐先上InfluxDB。顺便说个数据量估算的方法。我这次30台注塑机每5秒上报一次数据每台设备每天产生17280条记录30台一天就是51.8万条。假设每条数据100字节一天约50MB原始数据。InfluxDB压缩后大概能缩到原始数据的十分之一30天存储量也就150MB左右。所以一般的车间项目一台普通服务器或者高性能工控机完全够用不需要上分布式集群。2.3 可视化与流编排Grafana、Node-RED、ThingsBoard的分工可视化是物联网平台最容易出彩也是客户最关注的部分。很多人上来就问“用哪个可视化工具”但我的经验是先搞清楚你要展示什么、给谁看。给操作工人看的产线大屏讲究实时、简洁、大字号。这种情况我用Grafana连接InfluxDB数据源直接拖拽出实时曲线和统计面板。Grafana的图表类型丰富告警状态、设备状态、能耗趋势都能画得漂亮还支持自定义告警通知。给设备工程师看的设备详情页讲究历史曲线、参数对比、事件记录。这种情况可以用ThingsBoard它自带设备资产模型、设备影子、告警管理能跟EMQX通过MQTT对接设备状态变化可以直接在平台里看到。给IT/自动化工程师做的集成逻辑比如设备数据清洗、格式转换、联动控制我会用Node-RED。它是一个可视化流编排工具把多个节点用线连起来就能实现一套逻辑。比如一条MQTT消息进来先解析JSON再判断数值是否超限超限就发HTTP请求到企业微信机器人同时写入MySQL。这种流在Node-RED里十来分钟就能搭好。不过要提醒一句ThingsBoard社区版虽然功能强大但它默认的Docker Compose会拉起Kafka、Elasticsearch、PostgreSQL一堆服务资源占用非常夸张。我第一次跑官方compose时4GB内存的机器直接被卡死。如果你只是想快速看到设备数据、跑通流程建议先用“EMQX InfluxDB Grafana Node-RED”这套轻量组合。等确实需要设备管理、资产管理了再把ThingsBoard加进来也不迟。3. 实操过程用Docker Compose一小时搭起本地物联网平台3.1 环境准备与端口规划开始部署之前先把硬件和端口规划好这一步省掉后面一大半的麻烦。硬件方面我们这次用的是客户淘汰的一台工作站16GB内存、8核CPU、一块512GB SSD跑这套轻量组合绰绰有余。如果你有NVIDIA GPU后面打算接本地大模型那建议至少32GB内存GPU显存8GB起步。没有GPU也没关系用小模型跑CPU推理也能用只是响应速度慢一点。操作系统我就用Ubuntu 22.04 LTS安装完Docker Engine和Docker Compose插件后就可以开工。这里有个小坑Ubuntu自带的docker.io包版本往往比较旧一定要用官方源安装Docker Engine否则后面拉镜像、用Compose插件都可能出问题。端口规划上我先把整个平台会用的端口列成了一张表贴在工位上避免后面服务启动时才发现端口冲突服务端口说明EMQX MQTT1883设备接入端口TCPEMQX MQTT/SSL8883加密接入留作后续扩展EMQX Dashboard18083Web管理界面InfluxDB8086HTTP API端口Node-RED1880流编排编辑器Grafana3000可视化看板Ollama11434本地大模型API有个很容易忽略的点EMQX默认Dashboard端口是18083InfluxDB是8086Node-RED是1880Grafana是3000。这些端口如果跟公司内网其他系统冲突一定要在compose文件里提前改掉。我之前遇到过一台服务器上同时跑了Jenkins8080和另一个服务用了8083结果EMQX的Web管理端口8083被占用服务起来后Dashboard一直打不开排查了半天才发现是端口冲突。3.2 容器编排文件与启动验证环境准备好之后直接写docker-compose.yml。我先给出一份完整的、能直接用的编排文件version: 3.8 services: emqx: image: emqx/emqx:5.8.0 container_name: emqx ports: - 1883:1883 - 8883:8883 - 18083:18083 environment: - EMQX_NODE_NAMEemqx127.0.0.1 restart: unless-stopped influxdb: image: influxdb:2.7 container_name: influxdb ports: - 8086:8086 environment: - DOCKER_INFLUXDB_INIT_MODEsetup - DOCKER_INFLUXDB_INIT_USERNAMEadmin - DOCKER_INFLUXDB_INIT_PASSWORDadmin123456 - DOCKER_INFLUXDB_INIT_ORGiotlab - DOCKER_INFLUXDB_INIT_BUCKETiot_data - DOCKER_INFLUXDB_INIT_ADMIN_TOKENmy-super-secret-token-2024 volumes: - influxdb-data:/var/lib/influxdb2 restart: unless-stopped node-red: image: nodered/node-red:3.1.9 container_name: node-red ports: - 1880:1880 environment: - TZAsia/Shanghai volumes: - node-red-data:/data restart: unless-stopped grafana: image: grafana/grafana:11.1.0 container_name: grafana ports: - 3000:3000 environment: - GF_SECURITY_ADMIN_PASSWORDadmin123456 - TZAsia/Shanghai volumes: - grafana-data:/var/lib/grafana restart: unless-stopped volumes: influxdb-data: node-red-data: grafana-data:这个文件的几个细节值得说明一下InfluxDB的初始化环境变量是关键。第一次启动时它会自动创建管理员账号、组织org、存储桶bucket以及访问令牌token。后续所有写入InfluxDB的请求都要用到这个token所以那个my-super-secret-token-2024一定要记好最好改成一个你自己的随机字符串别照抄。Grafana默认账号是admin密码我通过环境变量直接改成了admin123456第一次登录不用再改也省得之后一遍遍输默认密码。restart: unless-stopped这个策略非常推荐。服务器重启或者容器异常退出后Docker会自动拉起容器对无人值守的机房环境特别重要。我见过有人没写这个参数半夜服务器重启了一下第二天早上设备数据全断因为MQTT Broker根本没起来。文件写好之后在对应目录下执行docker compose up -d然后等镜像拉取完成。拉镜像的时间取决于网络情况EMQX的镜像大约100多MBInfluxDB和Grafana也都不小。如果发现拉取超时先检查一下Docker的registry-mirrors配置是否设置了一个可用的源这个属于国内部署的基础操作。启动完成后逐个验证服务浏览器打开http://服务器IP:18083能出现EMQX Dashboard登录页默认账号admin、密码public浏览器打开http://服务器IP:8086能看到InfluxDB初始化界面浏览器打开http://服务器IP:1880进入Node-RED编辑器浏览器打开http://服务器IP:3000用admin/admin123456登录Grafana。四个页面全部能打开基础平台就算立住了。3.3 设备接入实测模拟数据从MQTT到InfluxDB再上大屏平台跑起来之后下一步就是设备接入。没有真实设备也没关系我先用Python写一个模拟器模拟30台注塑机的温度、压力数据每5秒上报一次走MQTT协议发到EMQX。模拟器代码不长核心逻辑就是循环连接EMQX构造JSON消息然后发布到固定主题import paho.mqtt.client as mqtt import time import json import random BROKER_HOST 192.168.1.100 BROKER_PORT 1883 USERNAME emqx_user PASSWORD emqx_pass TOPIC factory/injection/temperature client mqtt.Client(client_idsimulator_001) client.username_pw_set(USERNAME, PASSWORD) client.connect(BROKER_HOST, BROKER_PORT, 60) while True: for i in range(1, 31): payload { device_id: fINJ-{i:03d}, temperature: round(random.uniform(180, 220), 2), pressure: round(random.uniform(10, 30), 2), ts: int(time.time() * 1000) } client.publish(TOPIC, json.dumps(payload), qos1) print(f已发送一批数据当前时间: {time.strftime(%Y-%m-%d %H:%M:%S)}) time.sleep(5)注意这里我调用了username_pw_set也就是说EMQX上必须提前创建好这个认证用户。在EMQX Dashboard里找到“访问控制”→“认证”添加一个用户名密码认证数据源然后创建emqx_user/emqx_pass。MQTT Broker默认允许匿名连接但生产环境必须关掉匿名认证否则任何人都能往里发数据也能订阅所有设备的实时数据这是很容易被忽视的安全隐患。模拟器跑起来之后在EMQX Dashboard的“主题”页面能看到factory/injection/temperature主题有消息流动。接下来要把这些消息接入InfluxDB。在EMQX Dashboard里创建一条规则SQL大概是这样的SELECT clientid, payload.device_id as device_id, payload.temperature as temperature, payload.pressure as pressure, payload.ts as ts FROM factory/injection/temperature动作选择“数据转发到InfluxDB”填上InfluxDB的地址、组织、bucket、token并指定一个measurement名称。保存后消息就会自动写入InfluxDB的iot_data桶中。验证数据是否写入可以在InfluxDB的Web界面里执行一个最简单的Flux查询from(bucket: iot_data) | range(start: -10m) | limit(n: 20)能看到数据就说明整条链路已经通了。然后在Grafana里添加InfluxDB数据源选Flux查询方式建一个面板查询最近一小时temperature的平均值按device_id分组展示成时间序列曲线。到这里从设备模拟数据到可视化大屏的完整闭环就打通了。4. 本地AI增强把大模型接入物联网平台让数据自己开口说话4.1 Ollama本地部署与模型选型平台跑通之后如果只停留在“采集数据、展示曲线”这个层面其实还没发挥出本地部署的全部潜力。最近本地部署大模型这个话题热度极高Ollama、DeepSeek、RAGFlow这些工具的组合已经非常成熟完全可以把大模型能力接到物联网平台上做告警分析、维修辅助、数据问答。先部署Ollama。Ollama是目前最省事的本地大模型运行环境一行命令就能把模型跑起来而且提供REST API能被其他服务直接调用。# 在有GPU的机器上加上--gpus all参数并把默认端口映射出来 docker run -d --gpus all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama:latest # 拉取一个7B参数的模型日常分析够用 docker exec -it ollama ollama pull qwen2.5:7b模型选型上我个人的建议是机器内存16GB以内先跑qwen2.5:7b如果内存32GB以上或者有8GB以上显存可以上qwen2.5:14b或者同类别的更大模型如果只是做简单的分类、关键词提取3B~4B的小模型也够速度还快。7B模型在CPU上做简单推理单条请求大约几秒到十几秒作为异步分析完全够用如果要实时响应那就得靠GPU了。部署好Ollama后可以先做一个最简单的验证用curl调用它的APIcurl http://localhost:11434/api/generate -d { model: qwen2.5:7b, prompt: 一台注塑机连续5分钟温度超过210度可能是什么原因给出排查建议。, stream: false }能返回一段合理的文本回复就说明本地大模型已经就位。4.2 用Dify/RAGFlow构建设备知识库大模型本身的问题是它只懂通用知识对你这套具体的设备、你的工厂历史维修记录一无所知。要让AI真正能帮上忙得把企业的设备手册、历史维修记录、工艺参数文档喂给它这就用到了知识库工具。当前最主流的两个选择是Dify和RAGFlow。Dify的优势是应用编排能力很强。你可以创建一个“设备维修助手”应用把设备告警JSON数据作为输入先经过一个工作流节点把告警信息、设备编号、最近历史数据拼装成Prompt再调用Ollama里的模型生成分析结果最后把结果返回给前端。整个过程不需要写太多代码在网页上拖拽配置就行。RAGFlow的优势在于文档解析。如果你手头有几十页的PDF设备手册RAGFlow能把版面、表格、图片里的信息都解析出来存入向量库检索准确率比普通切片方案要高不少。两者也支持一起用RAGFlow负责把文档切成向量索引Dify负责做对话流程编排。这两套系统都属于“一个Docker Compose就能起”的类型部署方式官方文档写得很清楚。它们对内存的要求稍高建议至少8GB内存再跑。如果机器资源有限也可以先只部署Dify它本身自带知识库能力只是文档解析精细度不如RAGFlow。4.3 告警自动分析场景的实现示例设备接入、数据入库、大模型部署都完成之后我们来做一个完整的告警分析场景。场景设定注塑机INJ-003在连续5分钟内温度超过210度平台要自动生成一条告警并附带可能的故障原因、排查建议和历史上类似故障的处理记录。实现思路是这样的EMQX规则引擎实时监控温度数据当某台设备连续多次超过阈值时触发一条告警消息发布到alerts/injection主题Node-RED订阅这个主题收到告警后从InfluxDB查询该设备最近30分钟的历史数据把温度、压力、趋势信息整理成文本Node-RED把文本POST到Dify的“设备维修助手”应用APIDify的工作流先从RAGFlow向量库检索相关历史维修记录再将检索结果和告警信息一起组装成Prompt调用Ollama的qwen2.5:7b模型模型生成的分析结果再由Node-RED推送到企业微信机器人或者存入新的MQTT主题供Web端展示。这里面最核心的一段逻辑是第三步调用Dify API的HTTP配置。Dify的API请求格式如下curl --location --request POST http://localhost/app/api/chat-messages \ --header Authorization: Bearer app-xxxxx \ --header Content-Type: application/json \ --data-raw { inputs: { temperature: 212.5, pressure: 18.6, device_id: INJ-003 }, query: 这台注塑机温度偏高请给出可能原因和排查建议, response_mode: blocking, user: edge-user-001 }实际跑下来的效果模型会综合设备当前数据和历史维修知识生成类似这样的建议“温度偏高且压力波动明显优先检查模具冷却水路是否堵塞其次检查热电偶安装位置是否偏移历史记录显示INJ-003在2023年5月曾因冷却阀故障导致同类问题当时更换电磁阀后恢复正常。”这种输出对车间维修工来说比干巴巴看一个温度曲线图有用得多。而且整个链路全部跑在内网设备数据和维修知识都没有出过本地服务器。这正是本地部署物联网平台叠加本地大模型的最大价值。5. 常见问题与避坑实录5.1 高频问题速查表部署这套平台的过程中我整理了一份高频问题速查表都是实际踩过的坑问题现象可能原因解决办法EMQX Dashboard打不开端口18083未映射或防火墙没放行检查docker compose端口映射确认服务器防火墙放行18083MQTT客户端连不上EMQX开启了认证但用户没创建在Dashboard的“访问控制-认证”中创建用户设备数据写不进InfluxDBtoken错误或bucket名不对核对compose文件里的token以及EMQX规则中填写的InfluxDB配置Grafana查不到数据数据源选了InfluxQL但InfluxDB是2.xGrafana数据源查询语言切为Flux并写Flux查询语句容器重启后服务没起来compose文件漏写restart策略给每个服务加上restart: unless-stoppedNode-RED安装节点卡住npm默认源访问慢在Node-RED容器中设置npm镜像源后重试服务器时间不准导致数据时间错乱容器时区未设置compose文件中统一配置TZAsia/Shanghai5.2 三个容易忽略的细节直接影响项目成败第一个细节是QoS级别。MQTT消息有三种QoS级别0表示最多一次1表示至少一次2表示只有一次。很多人图省事用了QoS 0结果网络一抖动数据就丢了。物联网平台的数据是后续分析的基础我建议平台内部所有消息至少用QoS 1。代价是消息确认会多一点网络开销但对现在的网络环境来说完全不是问题。我实测过30台设备每5秒上报QoS 1对EMQX的影响几乎可以忽略但数据完整性明显提升。第二个细节是InfluxDB的时序数据时间戳单位。InfluxDB 2.x默认时间戳是纳秒级而很多设备上报的时间戳是毫秒级。如果你在EMQX规则里直接把设备的毫秒时间戳写入InfluxDB而不做转换查询出来的时间会偏离真实时间很多。我建议在写入时统一用now()或者让InfluxDB自动处理时间戳数据到达时间跟设备时间差个几秒对大多数分析场景没有影响。第三个细节是端口规划。平台本身组件不多但加上Node-RED、Ollama、Dify之后端口数量就上来了。我建议开工之前先画一张端口分配表把每个服务的端口固定好写进compose文件里的注释中同时跟客户的IT部门确认这些端口没有被其他系统占用。否则上线当天发现1883端口被某个内部系统占了临时改端口客户端配置又要跟着改一遍非常耽误事。踩过几次坑之后我个人的习惯是先花半小时把数据模型、端口、存储周期想清楚再开始写compose文件。部署这套本地物联网平台真正花时间的不是敲命令而是想清楚数据流、告警规则和AI分析逻辑。架构想透了剩下的都是体力活。这套方案后续还可以加边缘计算比如用eKuiper在网关侧做实时过滤和聚合、数字孪生可视化把设备数据映射到3D模型上、以及更细粒度的预测性维护模型。但不管怎么扩展本地的数据底座和AI底座都不会变。先把基础打牢后面做什么都有底气。

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

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

免费获取报价