基于Java全栈的物联网平台源码架构与实践拆解
简介:物联网平台是连接设备与业务应用的核心基础设施,其建设往往涉及设备接入、数据流转、可视化呈现等多个技术环节。在工程实践中,如何选型技术栈、设计数据链路,决定了平台的稳定性与扩展性。本文从基础概念出发,讲解物联网平台中常见的MQTT、TCP长连接协议接入原理,以及Spring Boot、Netty、Redis等核心组件在设备管理、数据缓存与推送中的作用。在应用层面,重点介绍组态编辑器和可视化大屏的工程实现思路,包括WebSocket实时订阅、图元绑定与渲染性能优化等关键技术点。面向智慧园区、工业监控等实际场景,这些方案能有效降低二次开发成本。最后以一套基于Java全栈的开源平台源码为样本,梳理从环境部署到功能跑通的完整路径,帮助读者规避常见坑位,快速构建可落地的物联网基础平台。 做物联网平台这几年,我前后接触过的开源项目少说也有十几套,Java全栈的、Go的、Node的都有。坦白讲,大多数号称“全栈物联网源码”的项目,要么只有一个后端加一个简陋页面,要么组态和大屏基本靠截图撑场面。这套基于Java全栈技术的最新版物联网平台源码,我花了一周时间完整跑通,从MQTT、TCP设备接入,到组态编辑、大屏可视化,再到海康摄像头集成,算是近年来看过的完成度相当高的一套。这篇文章不聊广告,只把我实际拆解这套源码时的架构思路、关键实现和踩坑记录整理出来。如果你正准备选型一套物联网基础平台,或者想自己从零搭一套,这篇应该能帮你省下不少时间。
1. 先聊聊这套源码给我的第一印象
1.1 拿到手先看什么:目录结构、启动方式和文档完整度
很多源码项目拿到手的第一步就劝退:没有说明文档、依赖包版本乱飞、数据库脚本缺失。这套源码让我比较意外的是,它的目录划分非常清楚,根目录下直接能看到几个核心模块:后端服务、前端控制台、大屏项目、组态编辑器,以及部署用的docker-compose文件。
我建议你拿到任何源码后,先别急着mvn install或者npm install,按下面顺序过一遍:
- 先看README,确认必须的中间件版本,比如JDK、MySQL、Redis、MQTT Broker。
- 再找数据库脚本,确认是MySQL还是PostgreSQL,建库脚本是否完整。
- 然后看配置文件,重点看
application.yml里数据库连接、Redis地址、MQTT连接参数是不是写死。 - 最后看启动脚本,确认有没有一键启动或者Docker编排。
这套源码在数据库脚本和初始化数据上做得比较到位,设备类型、产品物模型、菜单权限这些基础数据都带上了,省去了我手动造的麻烦。国内很多开源项目恰恰在这一步做得粗糙,导致光环境准备就要折腾两三天。
1.2 功能清单到底覆盖到了什么程度
从功能模块上看,这套源码覆盖了物联网平台常见的几个大块:
- 设备接入层:支持MQTT、TCP长连接,设备注册、鉴权、在线状态管理。
- 设备管理层:产品管理、设备管理、物模型、设备分组、固件升级的接口预留。
- 数据层:设备上报属性、事件、遥测数据的存储和查询。
- 组态模块:拖拽式组态编辑器,支持图元库、数据绑定、状态联动。
- 大屏可视化:独立的大屏工程,支持图表组件和实时数据刷新。
- 视频接入:海康摄像头接入,RTSP转Web播放。
- 系统管理:用户、角色、权限、操作日志。
我实际跑下来,设备接入、组态、大屏这三条线是真能工作的,不是那种只有路由没有业务逻辑的半成品。尤其是组态编辑器和大屏,前端代码量相当大,说明作者在这块下了不少功夫。
1.3 为什么Java全栈在这个场景里仍然能打
有人可能会问,现在物联网平台选型都在提Go或者Node,Java是不是太重了?我的看法是,Java全栈在传统工业物联网、智慧园区、能源管理这类场景里依然是主流选择,原因很实在:
- 团队招人容易,Java后端工程师供给量大,接手成本低。
- 生态成熟,Netty、Spring Boot、MyBatis Plus这些都是经过大规模生产验证的组件。
- 部署运维体系完善,Jenkins、Docker、Kubernetes对Java应用支持得很成熟。
- 很多私有化项目客户明确要求Java技术栈,方便后续二次开发。
这套源码没有盲目上微服务,而是采用模块化单体加消息队列的方式。对于大多数中小型物联网平台,单体能扛住相当大规模的设备接入,没必要一上来就拆成十几个微服务,这是我很认可的设计取向。
2. 整体架构与核心选型,每个选择背后都有原因
2.1 后端模块划分:Spring Boot + Netty + Redis + MySQL的组合
后端主体基于Spring Boot,这在预期之内。真正让我觉得有含金量的是它把设备接入层单独拆了出来,没有跟业务接口混在一起。
设备接入层用了Netty做TCP服务器,MQTT部分则对接了EMQX这类独立Broker。后端通过MQTT订阅设备上行数据,再统一处理后写入业务库和Redis缓存。这样的好处是,设备连接压力被Broker和Netty分担,业务服务不需要直接维持海量长连接。
模块划分大致如下:
iot-common:公共工具、统一返回结构、异常处理。iot-device:设备接入、协议解析、设备管理核心逻辑。iot-business:产品、设备、物模型等业务接口。iot-visual:组态和大屏相关的数据服务。iot-admin:系统管理模块。iot-video:摄像头接入和流媒体相关逻辑。
数据库选的是MySQL,时序数据部分在这套源码里是直接落到MySQL的,通过索引和分表来解决查询性能。如果设备量极大,可以再引入TDengine或InfluxDB,但作为一套基础平台,先用MySQL把业务跑通是务实的选择。
Redis承担的角色很多:缓存设备最新状态、保存设备会话信息、做分布式锁、缓存大屏聚合数据。设备上报的原始属性值会先更新到Redis里,再异步落库,页面查询时优先走缓存,这样大屏刷新不会把数据库打崩。
2.2 前端:Vue3 + 自研组态引擎 + ECharts
前端主框架是Vue3,控制台、组态编辑器和大屏是三个独立的前端工程,方便分开部署。
使用Vue3而不是Vue2,主要的收益是Composition API让组态编辑器这种复杂交互的代码组织更清晰,同时TypeScript的支持更好。组态编辑器没有依赖现成的开源图形引擎,而是自己基于Canvas和SVG实现了一套,这个后面第三部分细说。
大屏部分用了ECharts作为核心图表库,在一些特殊动效组件上做了封装。ECharts的生态完善,地图、关系图、仪表盘都够用,而且它对Canvas的渲染性能做了很多优化,适合大屏场景。
前端状态管理用的Pinia,数据请求用Axios,实时数据通过WebSocket推送。这套源码在WebSocket的封装上做得比较完善,支持按主题订阅,不是所有前端页面都收到全量数据,这是一个性能关键点。
2.3 数据链路:从设备上报到页面刷新的完整路径
我梳理了一遍设备数据流,大致是这么走的:
- 设备通过MQTT上报属性,消息进入EMQX。
- 后端一个专门的消费者服务订阅对应Topic,收到消息后做协议解析。
- 解析完成的数据进入统一的消息处理管道,做格式校验、单位转换、存储。
- 原始数据和最新值分别处理:最新值写Redis,历史数据批量落MySQL。
- 同时把数据变更事件推送到WebSocket服务端,按订阅关系推给前端页面。
- 大屏和组态页面收到WebSocket消息后,更新对应组件状态。
这条链路看起来不复杂,但每个环节都可能出问题。比如MQTT消息体格式不统一、设备上报频率过高导致消费者积压、WebSocket推送消息体过大导致页面卡顿。这套源码在这些地方都做了相应处理,比如消费者批量入库、WebSocket消息按点位ID订阅、前端做了渲染节流。
3. 组态模块:最容易被低估的硬骨头
3.1 组态编辑器要解决的核心问题
组态这个词从工业组态软件(像MCGS、FUXA这类)来的,核心目标是非程序员也能通过拖拽把设备状态做成一张可看的监控画面。但真正落地一个组态编辑器,难点远不是画几个矩形和圆,而是下面几件事:
- 画布模型:拖拽、缩放、对齐、组合、撤销重做。
- 图元库管理:图元怎么组织,怎么自定义。
- 数据绑定:图元的属性(颜色、文本、显隐)怎么和设备点位关联。
- 动画联动:数据变化怎么驱动图元刷新,且不卡顿。
- 发布与运行:设计态和运行态怎么分离。
这套源码在画布模型上做得比较完整,支持多选、对齐辅助线、图层管理,和Web版组态软件的基础体验已经比较接近了。
图元库按工业场景预置了管道、阀门、电机、传感器、仪表盘等常用图形。关键的思路是,每个图元不是一个死的图片,而是一个可配置的组件,属性面板里可以绑定点位和值域映射。比如一个阀门图元,开到位显示绿色,关到位显示红色,中间状态显示黄色,这些都是通过配置完成的,不用写代码。
3.2 数据模型怎么设计
组态项目的数据模型是这套源码里比较有参考价值的。一个典型的组态画面由以下几层组成:
- 项目(Project):对应一个组态工程,包含多个画面。
- 画面(Page):对应一页监控图,包含多个图元和画布配置。
- 图元(Element):画布上的具体组件,每个图元引用了图元库里的类型。
- 图元属性绑定(Binding):记录图元哪个属性和哪个设备点位绑定,以及值域映射规则。
- 实时数据源:运行时从Redis或WebSocket获取点位最新值,按绑定关系推给图元。
存储在数据库里就是几张表:组态项目表、组态画面表、图元实例表、绑定关系表。前端设计态保存的是JSON结构,JSON里直接包含图元位置、大小、图层、属性绑定等所有信息。运行时把JSON加载到画布引擎,引擎根据绑定关系订阅实时数据,驱动渲染更新。
我在自己做过组态类功能后有个体会:绑定关系千万别塞进图元JSON里然后让后端解析,前端自己负责绑定和渲染就够了,后端只保存JSON字符串和提供点位查询接口,职责清晰很多。这套源码就是这种模式。
3.3 常见组态场景的落地经验
跑通组态编辑器后,我拿一个真实的水泵房场景试了试,做了几个典型配置:
- 用一张水泵图片绑定电机的启停状态,状态为1时图片高亮并旋转,状态为0时恢复灰色。
- 用仪表盘图元绑定管道压力数值,设置量程0到1.6兆帕,超过1.2兆帕变色。
- 用文本图元绑定实时液位,保留一位小数。
- 两个泵之间画了一条管道连线,管道颜色跟随泵的运行状态变化。
这套配置全程没写一行前端代码,全部在属性面板里完成。实际操作中我遇到的唯一问题是图元库数量有限,一些行业专用设备图形需要自己做。不过它提供了自定义图元上传入口,用SVG图片就能扩展,总体满足率比预想高。
4. 大屏可视化,不只是把图表拼在一起
4.1 大屏布局:从自由拖拽到自适应缩放
大屏可视化这在很多项目里是面子工程,但又是必须的。这套源码的大屏工程没有用昂贵的商业大屏产品,而是自己实现了一套拖拽式布局。页面是自由画布,组件可以拖拽位置、调整大小,配置数据源,然后发布成独立页面。
大屏实现里最容易被忽略的是自适应。项目现场的大屏分辨率五花八门,常见的有1920乘1080、2560乘1440,甚至有些拼接屏分辨率更特殊。这套源码采用的是按设计稿比例缩放方案:设计时固定一个基准分辨率,运行时根据屏幕实际尺寸计算缩放比例,整体等比例缩放,避免组件错位。
小提示:这种整体缩放方案并非万能的,如果实际屏幕比例和设计稿差距过大,还是会出现上下黑边或左右留白。更稳妥的做法是设计稿尽量采用目标大屏的实际分辨率,并且要求客户提前给出屏幕参数。
4.2 实时数据推送:WebSocket与订阅模型
大屏页面要实时刷新,最原始的方案是定时轮询接口,比如每3秒请求一次最新数据。这套源码没有用轮询,而是走WebSocket推送。它的订阅模型我很认可:不是后端把全量大屏数据都推给所有连接,而是前端声明自己需要哪些点位或统计项,后端只往对应的连接推送相关数据。
举个例子,大屏上有三个图表组件,分别显示今日产量、设备在线率、告警数量。前端建立WebSocket连接后,会发送一个订阅消息,内容大致是“我要订阅device_count、online_rate、alarm_today 这三个指标”。后端维护一个订阅关系表,当指标数据更新时,精确推送给对应连接。
这样做的好处是数据量大时不会把每个浏览器都灌满无用消息,而且前端组件更新也更有针对性,不用每次都diff整个大屏数据对象。
4.3 性能优化:几十个图表同屏不卡
大屏页面几十个图表是很常见的,如果每个图表都独立渲染,浏览器很容易卡顿。这套源码在性能上有几个处理值得参考:
- 多个图表共用同一个WebSocket连接,只建立一个长连接,前端内部再做消息分发。
- 每个图表组件在收到数据后自行判断当前值是否和上一次渲染值相同,相同就跳过渲染。
- 数字翻牌器、仪表盘这类高频更新组件,做了requestAnimationFrame节流,避免频繁触发重绘。
- 后端聚合计算尽量在服务端完成,比如实时统计类指标由服务端定时计算后推送结果,前端不承担计算。
我实测在开了二三十个图表组件的大屏页面上,CPU占用和内存增长都还在可接受范围。如果组件数量继续增加,再往后可以考虑用Canvas自绘图表替代多个DOM型ECharts实例,但这套框架已经能满足绝大多数大屏项目的指标数量。
5. 通讯协议集成的细节,MQTT与TCP一个都不能少
5.1 MQTT接入:Broker选型、主题设计与断线重连
MQTT是物联网平台最常用的协议之一。这套源码的MQTT接入没有自己实现Broker,而是对接了EMQX,这个选型我举双手赞成。自己做MQTT Broker不是不行,但QoS、会话保持、遗嘱消息、集群这些要都做好,工作量非常大,直接用EMQX是性价比最高的方案。
接入层核心是主题设计。这套源码采用三级主题,逻辑清晰:
- 设备上行属性:
/dev/{productKey}/{deviceKey}/thing/event/property/post - 设备上行事件:
/dev/{productKey}/{deviceKey}/thing/event/{eventId}/post - 平台下行指令:
/sys/{productKey}/{deviceKey}/thing/service/invoke - 设备响应:
/sys/{productKey}/{deviceKey}/thing/service/invoke_reply
设备认证在MQTT层面通过clientId和用户名密码完成。clientId 规则一般是{productKey}.{deviceKey},密码用设备密钥或者动态生成的签名。这套源码里有签名算法工具类,支持设备端用HMAC-SHA256生成动态签名,安全性比明文密码好很多。
实际调试中我比较意外的坑是遗嘱消息。不少设备异常断电时不会主动发disconnect,平台端如果不处理遗嘱消息,设备会一直显示在线。EMQX里要配置遗嘱Topic为/sys/{productKey}/{deviceKey}/status,payload 里标记offline。这套源码对遗嘱消息做了处理,但如果你是从其他平台改过来的,一定要检查Broker的遗嘱配置。
5.2 TCP长连接:Netty拆包粘包与报文编解码
除了MQTT,很多DTU、PLC设备只支持TCP长连接,而且报文格式是私有协议,所以TCP接入在物联网平台里也必不可少。
这套源码基于Netty实现TCP服务端,核心是解决三个问题:
- 连接管理:设备上线、心跳、断线识别。
- 拆包粘包:TCP是流式协议,必须按帧分割报文。
- 业务解码:把字节数组解析成设备数据。
拆包粘包使用Netty自带的LengthFieldBasedFrameDecoder可以解决大部分场景。比如报文前4字节是消息长度,那么初始化时指定长度字段偏移和长度字段长度,Netty就能自动按帧切分。
ch.pipeline() .addLast(new LengthFieldBasedFrameDecoder(1024 * 1024, 4, 4, 0, 8)) .addLast(new ByteBufToDeviceMessageDecoder()) .addLast(new DeviceMessageHandler());如果设备协议是固定结束符(比如0x7E开头,0x0D0A结尾),那就改用DelimiterBasedFrameDecoder。关键是现场调试时必须先确认设备协议文档里规定的帧结构,否则解码器参数稍微错一点,就会出现整包错乱。
设备上报的原始数据往往不是直接可用的JSON,而是二进制或BCD码。这套源码里把每种设备协议实现为一个独立的Decoder,输出统一结构后再交给上层处理。设备登录取的是TCP连接建立后上报的第一个报文,里面包含设备编号,然后服务端将设备编号和Channel绑定,后续上报就能自动关联到设备。
5.3 多协议网关抽象,避免把协议写死在业务里
一个平台接的设备不可能只有一种协议。如果每种协议都直接调用业务服务,代码会变成一堆if-else。这套源码里有一个ProtocolAdapter接口,每一种协议对应一个实现类:
- MqttProtocolAdapter:负责MQTT消息解析。
- TcpProtocolAdapter:负责TCP报文解析。
- 后续扩展的Modbus、OPC UA、HTTP等协议,都按照同样的接口接入。
统一之后的协议消息模型包含设备编号、消息类型、属性点集合、上报时间,业务层完全不感知底层协议差异。这个抽象非常关键,因为物联网项目最大的特点就是设备接入的不可控性,协议抽象做得好,新设备接入的成本能降低一个量级。
6. 海康摄像头接入:ISAPI、RTSP与Web端播放
6.1 摄像头接入的三种方式
海康摄像头接入是这套源码的一大卖点。海康设备的接入方式常见有三种:
- ISAPI:海康私有HTTP接口,可以获取设备信息、查询通道、触发抓图、云台控制。
- OpenAPI:通过海康综合安防管理平台或者开放平台接口接入,适合大规模视频管理。
- RTSP:直接拉取摄像头的RTSP视频流,最通用,几乎所有网络摄像机都支持。
这套源码三种方式都有涉及,不过在完整跑通场景里,最常用的是ISAPI加RTSP的组合:用ISAPI来做设备发现和通道管理,用RTSP拉取视频流转封装成浏览器可播放的格式。
海康摄像头的RTSP地址格式大概是:
rtsp://admin:password@192.168.1.64:554/Streaming/Channels/101其中101表示第一路主码流,102表示第一路子码流。实际项目中,预览用子码流,回放用主码流,这样可以降低带宽压力。
如果你对接的摄像头品牌不是海康,其实思路一样,无非是ISAPI变成了大华的SDK或者ONVIF协议,RTSP地址格式不同而已。这套源码的设备管理里留了视频通道的抽象层,换品牌时主要改设备发现部分。
6.2 流媒体转换与Web播放方案
浏览器不能直接播放RTSP,这是做Web视频集成时绕不过去的问题。目前的通行做法是引入流媒体服务,将RTSP转成HTTP-FLV或HLS,再在前端用播放器播放。
这套源码集成了ZLMediaKit,这是一个很成熟的流媒体服务框架。它负责从摄像头拉取RTSP流,然后对外提供HTTP-FLV、HLS、WebRTC等输出协议。我在部署时用Docker跑了一个ZLMediaKit实例,配置好RTSP端口和HTTP端口后,调用它的REST API就能动态添加拉流代理。
curl -X POST http://127.0.0.1:8080/index/api/addStreamProxy \ -H "Content-Type: application/json" \ -d '{ "vhost": "__defaultVhost__", "app": "live", "stream": "camera_1001", "url": "rtsp://admin:password@192.168.1.64:554/Streaming/Channels/102" }'前端播放HTTP-FLV可以用flv.js,播放HLS可以用hls.js。如果对延迟要求高,可以走WebRTC,但WebRTC在跨网和复杂网络环境下有时打洞受限,后端又要多做一层信令服务。这三者的对比大概是:
| 协议 | 延迟 | 浏览器兼容性 | 适用场景 |
|---|---|---|---|
| HTTP-FLV | 1到3秒 | 需要flv.js,大部分现代浏览器可用 | 实时预览首选 |
| HLS | 5到15秒 | 原生支持较好 | 移动端查看、录像回放 |
| WebRTC | 0.5秒以内 | 现代浏览器普遍支持 | 对延迟极敏感的应急指挥场景 |
我在项目里默认先用HTTP-FLV,兼顾延迟和兼容性。如果客户要求秒开,再上WebRTC。
6.3 并发拉流与延迟控制的实测心得
摄像头接入并发是很多人忽略的点。假如平台有200路摄像头,200个用户同时点开预览,如果前端每个播放器都直接去向摄像头拉RTSP,摄像头立刻会被拉爆,网络带宽也扛不住。
正确的做法是:多个用户观看同一路摄像头时,流媒体服务器只维持一路上游拉流,下游转发给多个观看者。ZLMediaKit天然支持这种模式,同一个stream只要有人观看,就只维持一次源头拉流。这套源码里正好也是这么用的,把读流请求统一到流媒体服务,而不是让浏览器直连摄像头。
延迟控制方面,实测下来HTTP-FLV在局域网环境下延迟基本在1秒内,跨公网会高一些。如果延迟异常大,优先检查播放端是否启用了较大的buffer,以及上行网络是否有丢包。
另外还有一个小经验:海康摄像头默认会限制RTSP并发路数,有些型号默认只允许4路或者6路,超过后直接拒连。如果你做了大并发预览,要在摄像头后台把“最大取流路数”调高,或者用视频平台统一取流,不能完全依赖单摄像头能力。
7. 部署上线与运维排坑,这些坑我替你们踩过了
7.1 用Docker Compose编排一套最低可用环境
这套源码附带Docker Compose文件,我实际用下来,能够快速拉起一套可运行的环境。核心中间件包括:MySQL、Redis、EMQX、ZLMediaKit,加上后端和前端的容器。这里给一个精简版的结构参考:
version: '3.8' services: mysql: image: mysql:8.0 container_name: iot-mysql environment: MYSQL_ROOT_PASSWORD: root123456 MYSQL_DATABASE: iot_platform volumes: - mysql-data:/var/lib/mysql ports: - "3306:3306" redis: image: redis:7-alpine container_name: iot-redis ports: - "6379:6379" emqx: image: emqx/emqx:5.5 container_name: iot-emqx ports: - "1883:1883" - "8083:8083" - "18083:18083" zlmediakit: image: zlmediakit/zlmediakit:master container_name: iot-zlmediakit ports: - "1935:1935" - "554:554" - "8080:8080" volumes: mysql-data:注意一点:Docker Compose里的时区问题。默认容器时区是UTC,如果你的设备上报时间戳是北京时间,数据库里会出现8小时偏差。建议在服务环境变量里加上TZ=Asia/Shanghai,并在MySQL连接串上配置serverTimezone=Asia/Shanghai。
7.2 一个典型故障的完整排查链路:设备在线但页面无数据
我实际调试这套源码时,遇到过一个特别典型的故障:设备在EMQX管理后台显示在线,也能看到消息在持续收发,但前端页面始终没有数据。
我没有直接去看代码,而是沿着数据链路一段一段查:
- 第一步,看EMQX的Topic,确认设备是不是真在上报。通过EMQX Dashboard的Topic页面能看到消息流量,确认设备确实在发。
- 第二步,看后端日志,确认消费者是否订阅了对应Topic。发现日志里没有任何消息打印,说明订阅可能没建立。
- 第三步,检查后端配置里的EMQX连接参数,发现clientId配置重复了。两个后端实例用了同一个clientId,导致其中一个被EMQX踢下线,订阅自然失效。
- 第四步,修改clientId为实例唯一值后,消息正常进入消费者。
- 第五步,再检查WebSocket推送,确认前端收到消息并渲染。
这个问题绕了将近一个小时,最后原因特别简单:EMQX的clientId不允许重复,重复会导致互踢。这也是多实例部署时最常见的坑之一,排查顺序就是“设备到Broker、Broker到消费者、消费者到存储、存储到推送、推送到前端”,按链路逐层确认,比瞎猜代码高效得多。
7.3 资源限制、安全加固与日常维护建议
物联网平台部署后,运维侧有几个项目特别容易被忽视:
- 修改文件句柄限制。Netty长连接服务器在Linux下默认句柄数可能不够,需要调整
/etc/security/limits.conf,建议把 nofile 设为65535以上。 - 防火墙只开放必要端口。对外只需要开放Web端口和管理端口,MySQL、Redis、EMQX的内部端口不要直接暴露到公网。
- 启用认证。Redis至少设置密码,EMQX开启身份认证,MySQL不使用弱密码。这套源码默认配置里部分是空密码,上线前一定要改。
- 数据库备份。物联网平台的数据是持续增长的,至少要配置每日全量备份加binlog增量恢复。
- MQTT消息积压监控。如果消费速度跟不上设备上报速度,消息堆积会越来越大,需要监控消费者的Lag指标,并设置告警。
还有一个我在部署Java应用时经常遇到的坑,就是内存配置。JVM默认堆内存可能偏小,设备量上来后会出现OutOfMemoryError之类的报错。建议在启动参数里显式指定-Xms2g -Xmx2g,并且开启GC日志,方便后期排查问题。
写到这里,我最大的体会是:一套物联网平台源码,真正的价值不在“能跑”,而在于它的架构思路和细节处理能不能支撑你快速落地项目。如果你也想做自己的物联网平台,建议照着我上面拆解的链路去调整——先跑通设备接入,再做数据链路标准化,最后补组态和大屏这些上层应用。每一步踩过的坑,都是以后做项目时能直接带走的经验。
本文还有配套的精品资源,点击获取
