从零搭建轻量级物联网平台:架构设计与核心模块拆解
1. 为什么物联网平台值得自己搭一套物联网这个词听起来挺大但落到实际项目里无非就是三件事设备把数据传上来、平台把数据存下来、用户通过界面把数据看明白。市面上成熟的商业平台不少功能也确实全但用起来总有一种“租房子”的感觉——想改个墙面颜色得层层审批想加个隔断还得看物业脸色。对于想深入学习物联网架构、或者需要针对特定场景做二次开发的团队来说自己搭建一套轻量级平台反而比直接买服务更划算。我最早接触物联网平台搭建是在一个园区环境监测的小项目里。当时的需求很简单几十个温湿度传感器每隔几分钟上报一次数据后台能看实时曲线和历史报表就行。一开始想省事用现成的云服务结果发现设备接入协议不兼容数据格式要来回转换光是适配就花了一周多。后来索性自己搭从设备接入到数据存储再到前端展示整套流程走下来不仅把物联网的链路摸透了后续再加新设备、改新规则也顺手得多。这套“简单易用的物联网平台”核心价值就在于它把物联网平台最核心的骨架抽出来了包括设备管理、数据采集、规则引擎、可视化展示这几个模块。你可以直接拿来用也可以基于它做二次开发甚至把它当成学习物联网架构的活教材。适合的人群很明确物联网方向的在校学生、刚入行的嵌入式或后端开发者、需要快速验证产品原型的小团队以及想从传统软件转向物联网领域的工程师。提示自己搭平台不等于什么都从零写。合理利用开源组件和成熟框架把精力集中在业务逻辑和场景适配上才是高效的做法。2. 平台整体架构与核心模块拆解2.1 物联网平台的四层架构设计一套完整的物联网平台从下到上通常分为四层设备层、接入层、平台层、应用层。设备层就是各种传感器、执行器、网关接入层负责把设备数据收上来常见协议有MQTT、CoAP、HTTP等平台层是核心做设备管理、数据存储、规则计算应用层则是给最终用户看的界面和API。为什么这么分层因为物联网场景里设备种类多、协议杂、数据量大如果不分层代码会乱成一锅粥。比如你换了一种新传感器只需要在接入层加一个协议适配器平台层和应用层完全不用动。这种“高内聚低耦合”的思路是搭建任何物联网平台都要先想清楚的事。在这套平台里我建议接入层用MQTT协议作为主力。MQTT是发布/订阅模型特别适合设备数量多、网络不稳定的场景。设备只管往Broker发消息平台订阅自己关心的主题就行双方不用互相等待。相比HTTP的请求/响应模式MQTT在功耗、带宽、实时性上都更适合物联网。2.2 设备管理模块的关键设计设备管理是平台的“户口本”每个接入的设备都要在这里登记。核心字段包括设备ID、设备名称、设备类型、通信协议、在线状态、最后上报时间。设备ID必须全局唯一通常用MAC地址或芯片序列号实在没有就用平台生成的UUID。这里有个容易踩的坑设备在线状态的判断。很多新手直接用“最后一次上报时间”来判断超过5分钟没数据就标记离线。但实际场景里有些设备是定时上报比如每小时一次你设5分钟阈值就会误判。合理的做法是让设备支持心跳机制或者根据设备类型配置不同的超时阈值。我在项目里一般会加一个“设备影子”的概念把设备的最新状态缓存在平台侧即使设备短暂离线应用层读到的也是最后一次有效数据不会直接报错。设备分组和标签也很重要。当设备数量上百之后没有分组根本管不过来。可以按地理位置分、按设备类型分、按所属项目分。标签则更灵活比如给设备打上“重点监测”“备用”“测试中”的标签后续做规则和报表时可以按标签筛选。2.3 数据存储方案的选型对比物联网数据的特点是写入频率高、数据量大、近期数据查得频繁、历史数据偶尔查。这就决定了不能只用一种数据库。我的经验是“时序数据库关系型数据库”组合使用。时序数据库专门为时间序列数据优化写入速度快按时间范围查询效率高。常见的选择有InfluxDB、TDengine、TimescaleDB。关系型数据库则用来存设备信息、用户信息、规则配置这些结构化数据MySQL或PostgreSQL都行。数据库类型存储内容选型建议注意事项时序数据库设备上报的传感器数据TDengine国产、性能好或InfluxDB注意数据保留策略别无限存关系型数据库设备档案、用户、规则MySQL 8.0或PostgreSQL做好索引设备ID和时间字段必加缓存数据库设备最新状态、会话Redis设置合理的过期时间对象存储图片、固件、日志文件MinIO或云对象存储按日期分目录方便清理为什么这么搭配因为时序数据用关系型数据库存数据量一上来查询就会变慢而且压缩率低存储成本高。而设备档案这类数据用时序数据库存又不方便做关联查询。分开存各取所长是经过多个项目验证的稳妥方案。注意时序数据库的数据保留策略一定要提前规划。我见过一个项目传感器每秒上报一次半年后数据量到了几十亿条查询直接超时。后来加了按天分表和自动清理才解决。3. 从零搭建平台的核心实操步骤3.1 环境准备与基础组件安装先说一下我用的技术栈这套组合比较主流资料也多后端用Java Spring Boot或者Go前端用Vue或React消息中间件用EMQXMQTT Broker时序数据库用TDengine关系库用MySQL缓存用Redis。操作系统用Linux发行版就行Ubuntu 22.04或CentOS 7都可以。安装顺序有讲究。先装MySQL和Redis这两个是基础依赖。MySQL建库的时候字符集用utf8mb4排序规则用utf8mb4_general_ci避免中文乱码。Redis设置一个密码别裸奔。然后装TDengine安装完记得执行systemctl enable taosd设置开机自启。最后装EMQX默认端口1883是MQTT18083是管理后台。# 以Ubuntu为例安装MySQL和Redis sudo apt update sudo apt install mysql-server redis-server -y # 启动并设置开机自启 sudo systemctl start mysql redis-server sudo systemctl enable mysql redis-server # 安装TDengine需先下载对应版本的deb包 sudo dpkg -i TDengine-server-3.x.x-Linux-x64.deb sudo systemctl start taosd sudo systemctl enable taosdEMQX的安装更简单下载压缩包解压后直接运行./bin/emqx start就行。管理后台默认账号是admin密码是public第一次登录后立刻改掉。这里有个细节EMQX的配置文件在etc/emqx.conf如果要开启认证需要配置allow_anonymous false然后在Dashboard里创建认证用户。生产环境千万别允许匿名接入否则任何人都能往你的主题发数据。3.2 设备接入与MQTT主题设计设备接入的核心是主题Topic设计。MQTT主题是分层级的用斜杠分隔。我一般这样设计设备类型/设备ID/数据类别。比如sensor/device001/temperature表示device001这个传感器的温度数据。这样设计的好处是平台订阅sensor//temperature就能收到所有传感器的温度数据加号是单层通配符。设备端用MQTT客户端库连接Broker上报数据时把JSON格式的payload发到对应主题。payload里至少包含时间戳、数值、单位。时间戳用毫秒级Unix时间别用字符串格式省得解析麻烦。{ ts: 1718000000000, value: 25.6, unit: ℃, deviceId: device001 }平台侧收到消息后先做数据校验检查设备ID是否已注册、数值是否在合理范围。校验通过后写入时序数据库同时更新Redis里该设备的最新状态。这里有个性能优化点不要每条消息都单独写数据库可以攒一批再批量写入。TDengine支持批量插入一次写几百条比一条条写快得多。提示MQTT的QoS等级选择要结合场景。QoS 0最多一次可能丢数据QoS 1至少一次可能重复QoS 2恰好一次但开销大。传感器数据一般用QoS 1就够了平台侧做去重处理。3.3 规则引擎的配置与使用规则引擎是物联网平台的“大脑”负责根据设备数据触发动作。比如温度超过30度就发告警、湿度低于20%就打开加湿器。规则引擎的核心是“条件-动作”模型条件可以是数值比较、时间判断、设备状态组合动作可以是发通知、写数据库、调用外部接口。我一般用SQL-like的语法来配置规则这样非开发人员也能看懂。比如SELECT temperature, deviceId FROM sensor_data WHERE temperature 30 AND deviceId IN (SELECT id FROM devices WHERE group_id greenhouse)这条规则的意思是从传感器数据里选出温度大于30度的记录且设备属于“greenhouse”分组。触发后可以配置动作比如发送邮件、写入告警表、调用Webhook。规则引擎的实现方式有两种一种是平台内置的规则配置界面用户点选条件另一种是允许用户写脚本比如JavaScript或Lua。前者易用但灵活性差后者灵活但门槛高。我的建议是两者都支持简单规则用界面配复杂逻辑用脚本。脚本执行一定要加超时和资源限制防止死循环把平台拖垮。3.4 可视化展示与API开放可视化是给最终用户看的核心是实时曲线、历史报表、设备地图、告警列表这几个页面。前端图表库用ECharts或Chart.js都行ECharts功能更全适合做复杂的仪表盘。实时曲线用WebSocket推送数据别用轮询否则设备一多服务器扛不住。API开放是平台扩展性的关键。至少提供RESTful API让第三方系统能查设备列表、读历史数据、下发控制指令。API要做认证和限流认证用JWT或API Key限流用令牌桶算法。我一般会给每个API Key设置每分钟最大请求数防止被恶意刷接口。API类别典型接口认证方式限流建议设备管理增删改查设备JWT100次/分钟数据查询查历史数据、最新数据API Key500次/分钟指令下发向设备发控制指令JWT签名50次/分钟告警管理查告警、确认告警JWT200次/分钟4. 二次开发与学习进阶路线4.1 二次开发的常见切入方向拿到这套平台后二次开发通常从这几个方向入手加新协议适配、加新数据存储、加新告警方式、加新可视化组件。比如你接了一种用CoAP协议的设备就需要在接入层写一个CoAP适配器把数据转成内部统一格式再走后续流程。加新告警方式也很常见。平台默认可能只支持邮件告警你想加短信或钉钉通知就在规则引擎的动作列表里加一个“钉钉通知”动作实现一个发送HTTP请求的类就行。这种插件化的设计让平台能不断扩展而不影响核心逻辑。二次开发时要注意版本管理。我建议用Git做代码管理主分支保持稳定开发新功能开feature分支。数据库变更用Flyway或Liquibase做版本控制别手动改表结构否则多人协作时容易冲突。4.2 学习物联网平台的推荐路径如果你是想通过学习这套平台入门物联网我建议按这个顺序来先跑通设备模拟器发数据到平台理解MQTT的发布订阅模型然后看平台怎么存数据理解时序数据库和关系库的分工接着配一条规则引擎看数据怎么触发动作最后改前端页面加一个自定义图表。每一步都要动手光看代码没用。设备模拟器可以用Python的paho-mqtt库写几十行代码就能模拟一个传感器。改前端的时候先从改颜色、改文字开始再试着加一个新页面。遇到不懂的先看日志日志里通常有线索。提示学习过程中建议自己画架构图和数据流图。画图的过程就是梳理思路的过程很多想不明白的地方一画图就清楚了。4.3 从单机到集群的扩展思路单机版平台跑通之后如果设备量上来了就要考虑扩展。扩展的第一步是把无状态的服务多实例部署比如API服务可以起多个前面挂Nginx做负载均衡。MQTT Broker可以用EMQX集群多个节点组成一个集群设备连到任意节点都能互通。数据库的扩展更复杂。时序数据库TDengine支持多节点集群加节点就能提升写入和查询能力。MySQL可以做主从复制读走从库写走主库。Redis可以用哨兵模式或集群模式做高可用。扩展的时候要注意数据一致性。比如设备状态缓存在Redis里多个API实例同时更新同一个设备状态就可能出现覆盖。解决办法是用Redis的原子操作或者给设备状态加版本号更新时检查版本。5. 实操中常见问题与排查技巧5.1 设备连不上平台的排查清单设备连不上是最常见的问题排查按这个顺序来先看网络通不通用telnet或nc测Broker的1883端口再看认证过不过检查用户名密码或证书是否正确然后看主题权限有些Broker配置了ACL设备只能发特定主题最后看防火墙云服务器安全组和本机iptables都要检查。我遇到过一次诡异的情况设备能连上Broker但平台收不到数据。查了半天发现是主题订阅写错了平台订阅的是sensor//data设备发的是sensor/device001/datas多了个s。这种拼写错误很隐蔽建议主题命名规范定好之后写进文档别随手改。5.2 数据写入性能瓶颈的优化数据写入慢通常有三个原因单条写入、索引过多、磁盘IO瓶颈。优化手段对应着来改批量写入一次攒500到1000条检查时序数据库的索引只给必要的字段建索引如果磁盘IO是瓶颈换SSD或者加内存做缓存。TDengine有个参数叫maxRows控制单次插入的最大行数默认是4096。如果批量写入的数据超过这个数会被拆成多次插入。可以适当调大但别超过硬件承受范围。另外TDengine的keep参数控制数据保留天数默认是3650天根据实际需求调小能省不少磁盘空间。5.3 规则引擎误触发与漏触发规则引擎误触发一般是条件写得太宽比如temperature 30但传感器偶尔跳变到30.1又马上回落就会触发一次告警。解决办法是加持续时间条件比如temperature 30持续5分钟才触发。漏触发则可能是数据没到规则引擎检查MQTT订阅是否正常、规则是否启用、条件字段名是否匹配。还有一个坑是时区问题。规则里如果涉及时间判断比如“只在工作时间告警”要确保平台和设备的时区一致。我见过一个项目设备用UTC时间平台用本地时间结果告警在半夜疯狂触发。统一用UTC时间存储展示时再转本地时区是最稳妥的做法。常见问题可能原因排查方法解决方案设备离线网络中断、心跳超时查设备日志、ping Broker检查网络、调整心跳阈值数据丢失QoS 0、写入失败查Broker日志、数据库日志改用QoS 1、加重试机制查询超时数据量过大、索引缺失看慢查询日志加索引、分表、加缓存告警风暴规则条件过宽看告警记录时间分布加持续时间条件、告警去重内存溢出缓存无过期、连接泄漏看JVM或Go的pprof设过期时间、修复连接池5.4 平台安全加固的实操建议安全这块不能省。MQTT必须开认证别用默认密码。API必须走HTTPS别用HTTP裸奔。数据库别对公网开放只允许内网访问。设备接入可以加一机一密每个设备一个独立密钥丢了就吊销那一个不影响其他设备。日志里别打印敏感信息比如密码、密钥、完整的数据包。我见过一个项目日志把MQTT密码打出来了被有心人看到直接连上来发垃圾数据。日志脱敏要做在写日志之前别指望事后过滤。注意平台上线前一定要做一次安全自查包括默认密码是否修改、无用端口是否关闭、数据库是否限制访问来源、API是否有频率限制。这几项做完能挡住大部分低级攻击。6. 一些个人体会和后续扩展方向这套平台我前后搭过三次每次都有新收获。第一次搭的时候追求功能全什么协议都想支持结果代码臃肿得不行维护起来很痛苦。第二次做减法只保留MQTT和HTTP两种接入方式代码清爽多了反而更稳定。第三次加了规则引擎和可视化整个平台才真正有了“产品”的样子。我的体会是物联网平台的核心不是支持多少种协议而是数据从设备到用户的链路是否顺畅、是否可靠、是否容易扩展。协议可以后面加但架构一开始就要想清楚。另外别小看文档和注释过三个月再回来看代码没有文档你连自己写的都看不懂。后续扩展的话可以往边缘计算方向走。把一部分规则引擎下沉到网关数据在本地先处理一遍只把关键数据传上云。这样能减少带宽消耗也能提高响应速度。还可以加设备固件升级功能通过平台远程给设备推固件这在设备量大之后是刚需。最后分享一个小技巧平台上线后做一个简单的健康检查页面把Broker连接数、数据库写入速率、API响应时间这几个关键指标展示出来。不用多复杂一个HTML页面加几个定时请求就行。但有了它平台出问题你能第一时间发现比等用户投诉强得多。

相关新闻

ROS与STM32串口通信实战:从硬件接线到协议解析

ROS与STM32串口通信实战:从硬件接线到协议解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 6:36:54 阅读更多 →
DMA读旧数据?三招搞定Cache一致性难题

DMA读旧数据?三招搞定Cache一致性难题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 6:36:54 阅读更多 →
STM32寄存器操作实战:从GPIO到DMA的底层开发指南

STM32寄存器操作实战:从GPIO到DMA的底层开发指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 6:36:54 阅读更多 →

最新新闻

普通个人电脑跑大模型:显存、量化与CPU+GPU混合推理实战指南

普通个人电脑跑大模型:显存、量化与CPU+GPU混合推理实战指南

前阵子有个朋友问我:“普通个人电脑到底能跑多大的大模型?”我当时没直接甩个数字给他,因为这个问题本身就是一个“多变量博弈”:同样叫“7B”的模型,float16 版本和 int4 量化版本,显存需求能差出三倍&…

2026/10/19 7:16:12 阅读更多 →
个人电脑跑大模型:显存、量化与CPU/GPU混合推理实战指南

个人电脑跑大模型:显存、量化与CPU/GPU混合推理实战指南

经常有人问我:“我的电脑就一块普通显卡,显存不大,到底能不能跑得动现在流行的大模型?”这个问题听起来很玄,其实拆开就是一笔账:大模型跑起来消耗多少显存,取决于它的规模,也取决于…

2026/10/19 7:16:12 阅读更多 →
ADPAM自适应双感知注意力:提升红外小目标检测的YOLOv11改进实践

ADPAM自适应双感知注意力:提升红外小目标检测的YOLOv11改进实践

中午刚从标注平台拉完一批红外测试图,视线还没从屏幕上挪开,我就把几个常用检测模型跑了一遍对比——YOLOv8n、YOLOv9t,还有最新的YOLOv11n。结果跟在座大多数做小目标检测的兄弟预想的一样:漏检一串,虚警一堆&#xf…

2026/10/19 7:16:12 阅读更多 →
当视频生成跑赢播放:VDN-H3如何用混合注意力重新定义实时AI视频

当视频生成跑赢播放:VDN-H3如何用混合注意力重新定义实时AI视频

当视频生成跑赢播放:VDN-H3如何用混合注意力重新定义实时AI视频 一个被忽视的瓶颈 2026年8月,MiniMax H3正式开源,33B参数的扩散Transformer、2K分辨率、15秒时长、原生立体声音频——参数表足够惊艳。但真正把H3跑起来的人很快会发现一个尴尬的现实:生成一段14秒的视频,…

2026/10/19 7:16:12 阅读更多 →
中枢炎症体外新模型|猫脑星形胶质细胞(BA)功能与科研应用解析

中枢炎症体外新模型|猫脑星形胶质细胞(BA)功能与科研应用解析

星形胶质细胞是中枢神经系统数量最多的胶质细胞,并非单纯的脑组织填充细胞,在脑发育、神经递质稳态维持、血脑屏障调控中承担关键作用。静息状态下,它维持离子平衡、清除突触间隙谷氨酸、分泌神经营养因子;当遭遇外伤、缺血、Aβ …

2026/10/19 7:16:12 阅读更多 →
CVE-2018-7600 漏洞分析:从 CVSS 评分到 Drupalgeddon 2 复现

CVE-2018-7600 漏洞分析:从 CVSS 评分到 Drupalgeddon 2 复现

实验环境 Kali GNU/Linux 2024.4Docker / Docker ComposeVulhubBurp Suite Community目标:Drupal 8.5.0,CVE-2018-7600一、CVSS 版本演化与 CVE-2018-7600 评分 1. CVSS v2 / v3 / v4 的主要区别版本发布时间核心变化局限性CVSS v22006基础指标、时间指标…

2026/10/19 7:15:12 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →