资讯动态

Thingsboard 3.1.0 源码编译全流程实战:环境配置、模块解析与数据库初始化

发布时间:2026/10/16 23:05:04 来源:尧图企业网站定制
编译 Thingsboard 3.1.0 源码听起来就像跑一条“mvn clean install”那么简单但亲自动手之后你会发现这个开源物联网平台的全量编译牵扯到 JDK 版本、Node 依赖、前端资源打包、数据库初始化甚至还有安装时自动建表那一堆环节。我从拉代码到把服务真正跑起来前前后后折腾了两天踩的坑比想象中多得多。这篇就围绕 Thingsboard 3.1.0 的源码编译写一份完整记录从为什么非要自己编译、环境怎么搭、模块怎么理解、命令怎么执行到编译完怎么初始化数据库并启动全部按实际操作顺序整理出来。适合正在做 IoT 平台二次开发、需要私有化部署 Thingsboard或者单纯想研究这套平台内部实现的人直接参考。1. 先想清楚为什么非要源码编译 Thingsboard 3.1.01.1 官方安装包和源码构建的本质差别Thingsboard 官方在 GitHub 上会发布每个版本的 release 安装包包括 deb 包、docker 镜像和 jar 包。看起来直接用这些是最省事的但实际做项目时会碰到几个绕不开的问题。官方包是通用配置很多东西在打包阶段就已经定死了。比如你希望把默认数据库从 PostgreSQL 改成别的存储方案或者在启动时去掉内置的 demo 数据初始化逻辑还想调整某个模块的日志级别这时候拿到官方 jar 只能通过运行时配置去碰运气很多编译期参数根本没有机会改。更麻烦的是如果业务上需要给 Thingsboard 增加自定义的规则节点、自定义 REST API或者把 MQTT 传输层的认证逻辑改掉那就必须拿到整份源码自己重编译。还有一个容易被忽视的点官方 release 包通常滞后于源码仓库一段时间。你需要某个修复补丁或新功能而它还没进入正式 release那就只能基于源码分支自己构建。我在实际项目中就碰到过 transport 模块某个 bug 在 3.1.0 的后续提交里修复了但官方还没发新版最后只能拉 v3.1.0 源码合入补丁重新编译。1.2 源码编译适合哪些使用场景做源码编译之前先判断自己是不是真的需要这条路。如果你是刚接触 Thingsboard、只想快速把平台跑起来看看界面那直接用官方安装包或 docker-compose 就好完全没必要一上来就啃源码编译。源码构建适合的是这三类人一类是做二次开发需要修改前后端代码一类是部署环境特殊比如离线内网、CPU 架构不是标准的 x86_64官方包用不了还有一类是想排查线上问题需要带着调试符号和源码位置去定位异常的人。我这次编译 3.1.0 的背景就是某一套 IoT 设备接入服务需要内网部署同时还要改动设备配置下发那一块的逻辑所以必须完整构建一次。搞清楚需求之后再往下走才不会在环境准备环节浪费时间。2. 环境准备JDK、Maven、Node.js 一个都不能少2.1 版本匹配是第一个坑Thingsboard 3.1.0 对构建环境有明确的版本要求这可以说是整个编译流程里最容易翻车的地方。官方文档里写的是 JDK 11、Maven 3.6.x、Node.js 12.x。这里特别注意JDK 8 和 JDK 17 都不行。JDK 8 编译会直接报错因为 Thingsboard 3.x 的代码已经用到了 Java 11 的 APIJDK 17 更麻烦Maven 编译时可能会遇到强封装导致的反射访问限制虽然可以通过--add-opens参数规避但 3.1.0 这个版本我没有验证过完整编译不建议拿生产时间去赌。Node.js 的版本同样关键3.1.0 的 UI 工程ui-ngx依赖的 node-sass、angular 构建链对 Node 版本非常敏感我用 Node 14 尝试构建时node-sass 的 binding 就直接编译失败后来切到 Node 12 才顺利通过。环境版本组合建议如下组件推荐版本说明JDKOpenJDK 11必须 11过高或过低都会出问题Maven3.6.33.6 系列即可Node.js12.18用于 ui-ngx 前端构建npm6.x随 Node 12 自带即可PostgreSQL11 / 12运行时数据库建议 122.2 手动安装与配置我是在一台 CentOS 7 的机器上操作的不过这些步骤在 Ubuntu 上大同小异。JDK 建议用yum或apt装系统包避免手动解压 tar 包带来的 PATH 配置问题。sudo yum install -y java-11-openjdk-devel java -version # 确认输出为 openjdk version 11.0.xMaven 直接下载二进制包解压放到/opt/maven然后把MAVEN_HOME和PATH写进/etc/profile.d/maven.sh。这里提醒一句不要用系统自带的旧版 MavenCentOS 7 的源里默认是 Maven 3.0解析 3.1.0 的 pom 文件会出问题。export MAVEN_HOME/opt/maven export PATH${MAVEN_HOME}/bin:${PATH} export JAVA_HOME/usr/lib/jvm/java-11-openjdkNode.js 的安装我是用 nvm 处理的因为后面想在不同 Node 版本之间切换排查前端依赖问题时特别有用。curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash source ~/.bashrc nvm install 12.22.12 nvm use 12.22.12 node -v npm -v3. 拉取 3.1.0 源码并看懂模块划分3.1 切换版本分支源码直接用 git 拉取然后切到标签v3.1.0。这一步没什么特殊操作但要注意切换前务必确认当前目录干净否则切标签时会因为本地修改冲突而中断。git clone https://github.com/thingsboard/thingsboard.git cd thingsboard git checkout v3.1.0如果下载速度不理想可以先浅克隆后再切标签例如git clone --branch v3.1.0 --depth 1这样仓库体积小很多。不过浅克隆会砍掉完整 history后面如果想把特定 commit 的补丁合进来就不太方便所以做二次开发的话建议还是完整克隆。3.2 模块结构速览Thingsboard 3.1.0 是一个多模块 Maven 项目根目录下的pom.xml聚合了所有子模块。整体结构大致是这样目录作用application/主服务包含启动器、控制器、REST API、WebSocket 等核心逻辑common/公共库包含工具类、消息抽象、数据模型dao/数据访问层封装了 PostgreSQL、Cassandra 等数据库操作rule-engine/规则引擎模块负责消息处理、规则节点执行transport/设备接入层细分为 mqtt、coap、http 等传输协议实现msgbus/消息总线抽象用于应用内部通信ui-ngx/Angular 前端工程是控制台和客户门户的页面源码看到这么多模块先别慌。实际上你执行父工程的一条mvn install命令Maven 会根据模块间的依赖关系自动决定构建顺序不需要手动逐个模块去编译。但理解这个结构对后面定位问题非常有帮助。比如我那次遇到启动后页面空白就知道大概率是ui-ngx构建出来的静态资源没有被正确打进 jar 包而不是后端 Java 代码的问题。4. 完整编译流程从 Maven 到前端打包4.1 修改 Maven 仓库镜像与配置在国内网络环境下直接连 Maven Central 下载依赖会慢到让人失去耐心所以第一步建议先配置阿里云镜像。配置文件在~/.m2/settings.xml没有就新建一个。settings mirrors mirror idaliyun/id namealiyun maven/name urlhttps://maven.aliyun.com/repository/public/url mirrorOfcentral/mirrorOf /mirror /mirrors /settings同时根据机器内存情况设置 Maven 的 JVM 参数避免编译过程中 GC 压力过大。export MAVEN_OPTS-Xmx1024m -XX:MaxMetaspaceSize512m4.2 后端编译命令与参数解析环境准备好后在工程根目录执行编译。我实际使用的命令是mvn clean install -DskipTests -Dlicense.skiptrue -Ddockerfile.skiptrue -Dmaven.javadoc.skiptrue逐个解释为什么要带这些参数-DskipTests跳过单元测试。源码包里的测试用例不少而且有些测试依赖外部数据库跑起来既慢又不稳定编译阶段直接跳过最省事。-Dlicense.skiptrue跳过许可证头检查。Thingsboard 的构建过程默认会检查每个源文件的 license 头还会通过网络拉取许可证模板网络不好时经常卡死在这里。-Ddockerfile.skiptrue跳过 Dockerfile 相关插件执行编译时不需要产出镜像。-Dmaven.javadoc.skiptrue跳过 javadoc 生成纯提速用。如果你不需要修改前端想先把后端链路跑通可以加上-Dnpm.skiptrue跳过 ui-ngx 的 npm 构建。但这样打出来的 jar 包是不含前端页面的启动后访问 8080 端口会看到空白页。所以最终落地还是要完整编译前端。clean install和clean package的区别我多说一句。install会把构建好的模块安装到本地 Maven 仓库后续子模块依赖时不用反复去远程或 reactor 里找package只是生成当前模块的构建产物。多模块项目里用install更稳妥尤其是二次编译单个模块时依赖已经躺在本地仓库里速度会快很多。整个编译过程我第一次跑大概用了 25 到 35 分钟其中大部分时间花在下载依赖和前端 npm install 上。如果发现某个模块编译报错不要直接重跑全量加上-pl和-am参数只编译相关模块更快例如mvn -pl application -am clean install -DskipTests -Dlicense.skiptrue4.3 前端 ui-ngx 的单独编译正常情况下父工程的 Maven 构建会自动触发 ui-ngx 的构建。但如果你要单独改前端就在ui-ngx目录下直接调用 Node 工具链。cd ui-ngx npm install npm run build:prod这里最容易踩坑的是 npm install 阶段。3.1.0 的前端依赖锁定在 package-lock.json 里但部分依赖包是从 GitHub 直接拉取的网络不稳定时容易失败。建议先设置 npm 使用国内镜像npm config set registry https://registry.npmmirror.com执行完成后构建产物会输出到ui-ngx/target目录。如果后端编译时没有跳过 npm这部分内容最终会被 Maven 插件复制进 jar 包的静态资源目录也就是application/src/main/resources/static。5. 编译中常见的错误与排查方案5.1 Maven 层面的经典报错第一个经典报错是Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin开头的编译错误后面往往跟着release version 11 not supported。这种情况十有八九是 JDK 版本不对Maven 使用的 JVM 不是 11。先用mvn -version确认 Java 版本再检查JAVA_HOME环境变量是否指向 JDK 11。第二个常见问题是依赖解析失败报错类似Could not resolve dependencies for project org.thingsboard:application:jar:3.1.0。原因通常是某个模块没有被 install 到本地仓库或者网络问题导致远程依赖没拉全。处理方式是先对本模块的父模块执行一次mvn clean install -DskipTests保证依赖就位如果依然报错把~/.m2/repository下对应的缓存目录删掉重新拉取一次。还有一类是构建到一半卡在 license 检查。表现就是日志停在Checking licenses...或者下载 license 模板时长时间没动静。直接加-Dlicense.skiptrue跳过。第三个是 checkstyle 或 findbugs 插件报错这类静态检查经常因为代码规范问题中断构建。构建阶段可以直接跳过mvn clean install -DskipTests -Dlicense.skiptrue -Dcheckstyle.skiptrue -Dspotbugs.skiptrue5.2 Node.js 与 npm 构建故障前端构建报错集中在两类。一类是 node-sass 安装或编译失败典型日志是gyp ERR! stack Error: EACCES: permission denied。这是因为 node-sass 需要下载预编译二进制或者本地编译Node 版本和系统环境不匹配。解法很简单切换到 Node 12 并重装依赖nvm install 12.22.12 nvm use 12.22.12 rm -rf node_modules package-lock.json npm install另一类是JavaScript heap out of memory。Angular 的生产构建对内存消耗很大默认堆内存不够时直接崩溃。设置环境变量扩大 Node 内存即可export NODE_OPTIONS--max-old-space-size4096如果你不想每次都在终端里手动导出也可以在ui-ngx/package.json的 build 脚本里加上--max-old-space-size参数比如build:prod: node --max-old-space-size4096 node_modules/angular/cli/bin/ng build --prod。5.3 编译慢和资源问题的处理源码编译最考验耐心的是等待。除了网络镜像加速之外还可以做这么几件事。第一跳过不必要的模块。比如你只需要主服务和 MQTT 传输就用-pl application,transport/mqtt -am组合减少无关模块的编译时间。第二关闭病毒扫描或文件实时索引工具这类工具会持续扫描编译产生的临时文件严重拖慢 IO。第三给 Maven 和 Node 都预留足够内存不要在小内存机器上同时跑多个编译任务。首次编译完成之后后续增量编译会快很多因为依赖已经缓存到了本地仓库和 npm cache 里。所以如果你只是改了少量 Java 代码直接mvn -pl application -am install -DskipTests就可以基本两三分钟能出结果。6. 编译成功之后初始化数据库并启动服务6.1 生成运行包与配置编译完成之后最终产物在application/target目录下核心文件是thingsboard-3.1.0.jar这是一个 Spring Boot 的可执行 fat jar内置了 Tomcat 和前端静态资源。运行前需要准备数据库。3.1.0 默认使用 PostgreSQL先在数据库中创建用户和库CREATE DATABASE thingsboard; CREATE USER tb_user WITH PASSWORD tb_password; GRANT ALL PRIVILEGES ON DATABASE thingsboard TO tb_user;Thingsboard 的配置项可以直接通过环境变量传递也可以从源码目录复制官方配置文件后修改。实际部署时我更推荐用环境变量方式简单直接不用去翻 YAML 文件。启动前至少需要设置以下变量export DATABASE_ENTITIES_TYPEsql export DATABASE_TS_TYPEsql export SPRING_DATASOURCE_URLjdbc:postgresql://localhost:5432/thingsboard export SPRING_DATASOURCE_USERNAMEtb_user export SPRING_DATASOURCE_PASSWORDtb_passwordDATABASE_ENTITIES_TYPEsql表示实体数据存 PostgreSQLDATABASE_TS_TYPEsql表示时序数据也存 PostgreSQL。如果你没启用 Cassandra这两个值必须设成 sql否则启动会报错提示找不到时序数据库。6.2 数据库初始化首次启动前需要执行数据库安装命令它会自动建表、创建系统管理员账号并且写入基础配置数据。java -jar application/target/thingsboard-3.1.0.jar --install这一步执行时不要用nohup丢后台因为执行完会自动退出日志里能看到ThingsBoard has been successfully installed类似的信息。初始化完成后再正式启动服务java -jar application/target/thingsboard-3.1.0.jar启动日志出现Started Thingsboard Server之后访问http://服务器IP:8080就能看到登录页面。默认系统管理员账号是sysadminthingsboard.org密码sysadmin租户管理员账号是tenantthingsboard.org密码tenant。生产环境登录后第一件事就是改密码这个应该不用多强调。6.3 验证登录和下一步建议能登录控制台只代表基础服务通了真正的验证要建一个设备然后用 MQTT 客户端发一条消息过去看设备是否显示在线。我在源码编译后验证时碰到过一个问题设备接入正常但控制台不显示遥测数据。检查后才发现是初始化时DATABASE_TS_TYPE没有设置时序数据全写到内存里服务重启就丢了。重新设置环境变量并删掉旧库重建后数据才正常显示。如果想跑完这一步之后继续二次开发建议用 IDE 直接调试源码。把application模块作为 Spring Boot 应用启动前端用 Angular 的 dev server 跑在 4200 端口通过代理指向 8080这样改前端代码可以热更新不用反复打包 jar开发效率会高非常多。当然这属于源码编译之后的下一个话题了先把构建运行链路走通后面一切才好说。我个人在实际操作中的体会是Thingsboard 3.1.0 的源码编译本身没有太多高深的技术难点最花时间的反而是在环境匹配和依赖下载上。JDK、Node、Maven 三个版本哪怕有一个不对报错信息都会把你往错误的方向带。所以如果你准备自己动手编译第一步不是急着敲命令而是老老实实把环境版本跟官方要求对齐。最后再分享一个小技巧所有编译参数不要一个个手敲写进~/.m2/settings.xml的 profile 里或者直接存成一个build.sh脚本下次重新构建或换机器部署的时候一行命令就能复现整套流程省下来的时间够你多排查几个编译报错了。

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

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

免费获取报价 →
↑