拓冰建站拓冰建站
首页 / 资讯中心 / 正文

ThingsBoard 3.4.4源码编译安装全流程详解

简介针对 ThingsBoard 3.4.4 源码编译与安装的实操资源面向物联网平台二次开发或自建部署的开发者内容覆盖从环境准备到线上发布的完整链路。包含 Java 与 Maven 环境变量配置、Node 和 Yarn 版本一致性处理、PostgreSQL 安装、fetched 依赖组件下载、编译打包、数据库初始化以及最终部署七个阶段每个步骤都经过实际运行验证能帮助读者避开版本冲突、依赖缺失和数据库连接失败等典型问题。资源共 129 个文件以 dll 动态库、exe 和 msi 安装程序、txt 说明文档为主另含 xml / json 配置文件、pem 安全证书、rpm 软件包以及 Windows 与 Linux 两种平台的二进制组件压缩包整体约 784MB适合在两种操作系统下对照使用。目前已有 626 人学习下载适合具备一定 Linux 基础、希望从源码构建 ThingsBoard 的物联网工程师快速上手。 在某个物联网设备接入项目的改造中我需要给 ThingsBoard 换成一套全新的租户隔离逻辑下载官方编译好的发行包折腾了三天——改一行代码就要重新走一遍安装脚本最后实在扛不住才老老实实去折腾 3.4.4 源码编译安装。这一趟下来我最大的感受是ThingsBoard 这种级别的开源物联网平台如果你只是部署试用那直接下载发行包就够了但如果你想改业务逻辑、调启动流程、甚至扒开某个中间件的封装源码编译几乎是绕不开的一条路。这篇内容是从零开始跑通 ThingsBoard 3.4.4 源码编译安装的全过程记录包含环境版本选择、Maven 构建、前端 Angular 编译、数据库初始化、配置文件调整以及我在实操中遇到的一堆坑。无论你是准备做物联网毕业设计还是公司项目需要私有化部署物联网平台照着这套步骤走下来至少能省下两三天反复试错的时间。1. 为什么从源码编译安装官方发行包满足不了的场景1.1 源码编译和官方发行包的实质差异ThingsBoard 官方提供两种快速部署方式一是直接下载编译好的安装包通过install.sh一键安装二是用 Docker 镜像拉起来就跑。这两种方式对“只想用平台”的人来说非常友好但有个致命短板——你拿到的是一堆编译产物和数据库脚本平台的 Java 源码和前端 Angular 工程并不在你手里。源码编译出来的产物本质上是自己在本地把后端 Java 代码全部打包成可执行 jar同时把前端 Angular 代码编译成静态资源。二者组合起来就是一个“自己亲手生产”的完整平台包。这个过程中你能触及到源码级的配置比如消息队列的初始化逻辑、ORM 实体映射、网关路由拦截器这些都是发行包看不到的。1.2 哪些场景适合走源码编译从实际项目角度看以下四类场景我强烈建议直接源码编译别偷懒第一类是平台功能二次开发。比如要改设备的鉴权逻辑给 MQTT 接入增加自定义参数解析或者改 REST API 的返回字段这些都是后端核心代码必须重新编译。第二类是前端界面定制。ThingsBoard 的 UI 是 Angular 工程仪表盘、租户管理页面、设备详情页都得改源码后重新 build。官方发行包里的前端资源是压缩混淆过的改起来痛苦到怀疑人生。第三类是数据库或中间件深度适配。ThingsBoard 3.4.4 的默认配置是 PostgreSQL 本地内存队列但生产环境多半要接 Kafka、RabbitMQ 或者国产数据库这需要改配置甚至改源码里的驱动依赖。第四类是学习和研究平台架构。如果你在做物联网毕业设计或者想深入理解物联网平台运行机制把源码编译过程完整跑一遍远比读十篇源码解析文章来得实在——因为你会被迫搞清楚每一步构建依赖了什么。2. 环境准备与版本锁定JDK、Maven、Node、数据库一个都不能乱2.1 基础环境清单先列一下我这次编译用的环境组合3.4.4 实测下来最稳的一套组件版本说明操作系统Ubuntu 20.04 LTSCentOS 7 也可以但要用 root 或 sudo 权限JDKOpenJDK 113.4.x 系列强制要求 JDK 11JDK 8 编译直接失败Maven3.6.3 以上建议用 3.8.x太老的版本解析不好 Spring Boot 依赖Node.js14 或 16Node 17 编译前端会报 OpenSSL 错误经典大坑npm/yarnnpm 6前端依赖是通过 npm 安装的PostgreSQL12 及以上3.4.4 需要 PostgreSQL 12 以上的版本最好用 13 或 14Kafka可选如果队列不想用内存模式生产环境建议 2.82.2 版本锁定的隐藏约束关于版本这块多说几句这些都是我实际踩过之后才确认的JDK 版本卡得非常死。用 JDK 8 编译时会出现UnsupportedClassVersionError用 JDK 17 编译时又会遇到 Java 模块访问权限问题比如java.lang.reflect.InaccessibleObjectException。原因在于 ThingsBoard 3.4.4 底层依赖的 Netty、Spring Boot 版本对 JDK 模块化支持不完整。所以老老实实装 OpenJDK 11不要逞强。Node 版本的坑更隐蔽。ThingsBoard 3.4.4 的前端 UI 用的是 Angular 10 左右的版本底层是 Webpack 4。Webpack 4 调用的是 OpenSSL 1.1 的接口而 Node 17 开始内置的是 OpenSSL 3.0接口变了直接报ERR_OSSL_EVP_UNSUPPORTED。我当时用 Node 18 编译折腾了一晚上才定位到是这个原因。如果非要装高版本 Node编译时加NODE_OPTIONS--openssl-legacy-provider可以强行绕过但不想折腾的话直接用 Node 16 LTS 最省事。2.3 Maven 和 npm 加速配置源码编译绕不开依赖下载而 ThingsBoard 的依赖量非常大后端 Maven 依赖大概有几百兆前端 npm 包也有几百兆。国内网络环境下不配镜像基本没法干活。Maven 在~/.m2/settings.xml里配置阿里云仓库这是最基础的一步。npm 则用淘宝镜像npm config set registry https://registry.npmmirror.com。这两个配置到位后整个编译下载速度能提升好几倍而且能避免不少因下载超时导致的文件损坏问题。3. 源码获取与编译后端 Maven 构建全流程3.1 拉取 v3.4.4 分支并校验版本我从 GitHub 拉取的 ThingsBoard 官方仓库然后切到 3.4.4 的 taggit clone https://github.com/thingsboard/thingsboard.git cd thingsboard git checkout v3.4.4这里有一个细节值得注意master分支和v3.4.4分支的构建脚本有差异master 上可能已经升级了前端框架或者改动了模块结构。以我个人的经验做 3.4.4 的源码编译一定要严格切到v3.4.4tag否则后面构建出的二进制包可能跟 3.4.4 的配置结构对不上。3.2 后端构建命令与关键参数后端构建是整个编译的核心主命令如下mvn clean install -DskipTests有人会问为什么要加-DskipTests因为 ThingsBoard 的测试用例非常耗时而且很多集成测试需要依赖外部数据库和消息队列在本地构建阶段没必要全跑一遍。-DskipTests只跳过测试执行仍然会编译测试代码如果你想连测试代码都跳过可以改成-Dmaven.test.skiptrue但我不推荐因为后面调代码的时候测试类还有用。首次执行这个命令会持续很久我这边机器配置是 8 核 16G 内存大概跑了 25 分钟左右。如果不用镜像仓库这个时间可能会翻倍甚至因为依赖下载失败而直接中断。整个编译过程会以多模块方式产出各个子模块的 jar 包最终在application/build/libs目录下生成可执行的thingsboard-3.4.4-boot.jar。这个 boot jar 是 Spring Boot 的可执行 fat jar包含了后端运行需要的绝大多数依赖。3.3 前端 UI 构建路径与产物处理后端编译完成后还需要单独构建前端 UI。3.4.4 的前端工程在源码的ui-ngx目录下进入后执行cd ui-ngx npm install npm run buildnpm 安装阶段耗时比较长通常 10 分钟左右取决于网络环境。前端构建完成后会在target/thingsboard目录下生成编译好的静态资源文件。需要注意的是这个前端构建产物需要复制到后端运行包中才能被 jar 内部访问。实际上后端 Maven 编译时application模块有 maven-resources-plugin 或类似插件会自动把 ui-ngx 的构建产物嵌入到 boot jar 的static目录下。如果你先跑了前端npm run build再去跑后端mvn package最终产出的 boot jar 会包含前端页面如果你只想做纯后端调试那跑不带 UI 的 jar 也可以但 9090 端口访问不到界面。我建议的顺序是先执行完mvn clean install -DskipTests再执行前端npm run build最后重新执行一次mvn install -DskipTests不用 clean确保前端静态资源被封装进最终 jar。整个流程下来这个组合拳最稳。3.4 构建产物结构解读编译完成后产物主要有这么几块application/build/libs/thingsboard-3.4.4-boot.jar后端主程序ui-ngx/target/thingsboard/前端构建的无损静态资源调试时可以独立用 nginx 托管application/src/main/data/数据库初始化脚本含 schema.sql 和 system-data.sqlapplication/src/main/resources/thingsboard.yml后端核心配置模板这是后期部署调整的重头搞清楚这个结构后面部署和排错就会非常高效——比如前端样式出问题你只需要去ui-ngx/target看产物是否更新后端配置错误就直接从thingsboard.yml里找对应项。4. 安装部署数据库初始化与配置文件调整4.1 创建数据库与用户编译产物拿到手之后还不能直接启动因为 ThingsBoard 首次运行需要初始化数据库表结构和系统数据。先创建数据库CREATE DATABASE thingsboard; CREATE USER tb_user WITH PASSWORD tb_password; GRANT ALL PRIVILEGES ON DATABASE thingsboard TO tb_user;我记得在 3.4.4 里ThingsBoard 默认使用 PostgreSQL 的 public schema所以还要给用户授权 schema 权限\c thingsboard GRANT ALL ON SCHEMA public TO tb_user;这一步很多人容易漏不授权的话后面启动时会报permission denied for schema public。4.2 thingsboard.yml 修改要点从源码编译出来的东西不会像官方安装包那样给你生成一套现成的/etc/thingsboard配置目录所有配置都在 jar 包或者源码的 resources 目录里。你需要创建一个外部配置目录把源码里application/src/main/resources/thingsboard.yml复制出来然后按需修改mkdir -p /etc/thingsboard/conf cp application/src/main/resources/thingsboard.yml /etc/thingsboard/conf/修改的时候重点看这几项spring: datasource: url: jdbc:postgresql://localhost:5432/thingsboard username: tb_user password: tb_password jpa: hibernate: ddl-auto: none queue: type: in-memoryddl-auto: none很关键。ThingsBoard 的数据库表结构是通过schema.sql手动初始化的并不依赖 Hibernate 自动建表。如果你把ddl-auto改成update后面升级或者初始化时容易出各种脏数据问题。队列我用的in-memory单机测试没问题生产环境建议用 Kafka 并改成queue.type: kafka同时填上 Kafka 的 broker 地址。4.3 执行数据库初始化脚本数据库配置改好之后执行 SQL 初始化。这一步可以用 PostgreSQL 的命令行直接执行源码中的脚本psql -U tb_user -d thingsboard -f application/src/main/data/schema.sql psql -U tb_user -d thingsboard -f application/src/main/data/system-data.sqlschema.sql负责建表system-data.sql负责写入系统级基础数据包括默认的管理员账号、租户类型、权限定义等。执行顺序千万不能反不然外键关联会全部出错。此外3.4.4 里还有一个包含 demo 数据的脚本位置在application/src/main/data/demo-data.sql。如果只是学习测试可以执行这个脚本里面预置了设备、仪表盘和相关资产数据但如果要做正式项目初始化建议不要执行因为 demo 数据会污染业务系统。4.4 启动服务与浏览器访问初始化完成后直接用 java 启动 jarjava -Xms512m -Xmx1024m -jar application/build/libs/thingsboard-3.4.4-boot.jarThingsBoard 的默认 HTTP 端口是 9090启动成功后浏览器访问http://服务器IP:9090就能看到控制台登录页。默认管理员账号是sysadminthingsboard.org密码sysadmin。如果之前执行过 demo-data.sql租户管理员的账号是tenantthingsboard.org密码tenant。启动日志里有一个细节值得留意首次启动时平台会自动初始化一些管理员配置日志中会出现Started ThingsboardApplication就表示启动成功。如果端口被占或者数据库连不上会在启动早期直接抛异常退出日志里能看到具体原因。5. 编译安装路上的高频坑位排雷5.1 Maven 依赖仓库访问慢与依赖下载失败这个问题在我编译时排在首位。ThingsBoard 的模块很多依赖树非常庞大有些父 POM 中的插件在中央仓库下载速度极慢甚至超时中断。除了配置阿里云镜像之外我还有一个技巧在 settings.xml 中把阿里云仓库mirrorOf设为*同时让 Maven 使用并行下载能力。这样多个模块的依赖可以同时拉取整个构建时间能缩短不少。如果遇到Failed to read artifact descriptor这类报错通常是依赖包下载不完整。清理本地仓库中对应的.lastUpdated文件再重新执行mvn clean install -DskipTests就可以解决。5.2 Node 版本过高引发的 OpenSSL 错误前端构建时如果提示Error: error:0308010C:digital envelope routines::unsupported不要怀疑代码问题九成是 Node 版本太高Webpack 4 无法识别 OpenSSL 3.0。解决办法三种用 nvm 切换到 Node 14 或 16这是最优雅的执行export NODE_OPTIONS--openssl-legacy-provider后用 Node 18 编译实测也能通但会有弃用警告升级 Angular 相关依赖这个成本太高不推荐个人建议用 nvm 管理 Node 版本因为 ThingsBoard 这种老项目未来很可能需要你在多个 Node 版本之间切换nvm 是最省心的方案。5.3 前端构建内存溢出与资源限制npm run build到一半时如果报FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory这是构建内存不足不是代码问题。Angular 的 AOT 模板编译非常吃内存默认的 Node 堆内存上限约 1.5G不够用。解决办法是加大堆内存export NODE_OPTIONS--max_old_space_size4096如果同时设置了--openssl-legacy-provider要一起写进去export NODE_OPTIONS--max_old_space_size4096 --openssl-legacy-provider5.4 数据库连接权限与驱动不匹配启动时报connection refused或password authentication failed大部分情况是数据库配置和实际 PostgreSQL 认证方式不一致。我遇到过两次坑一是密码加密规则问题。PostgreSQL 15 开始默认用scram-sha-256而 ThingsBoard 3.4.4 使用的 JDBC 驱动版本较旧可能不完全兼容。建议安装 PostgreSQL 14 或 13或者手动把pg_hba.conf里的认证方式改成md5。二是 schema 授权问题。建库和建用户之后不要忘记执行GRANT ALL ON SCHEMA public TO tb_user;。ThingsBoard 初始化时会创建大量表和序列如果 schema 权限不足会频繁报错但报错信息可能比较隐晦不太容易直接联想到权限问题。5.5 启动后端口被占用与服务假死java -jar启动后如果进程还在但 9090 端口不监听可能是这台机器上已经跑了一个旧版 ThingsBoard或者别的服务占用了端口。用lsof -i:9090检查一下确认端口拿到之后再启动。还有一种“假死”情况日志停在某个初始化步骤不动看起来像卡住了。我在 3.4.4 上遇到过主要是本机内存不够平台启动时需要分配大量堆内存JVM 频繁 Full GC 导致启动极慢。这种情况可以先把-Xmx调低比如-Xmx512m等启动完成后再调回去如果机器内存充足建议直接给到 2G。6. 编译安装之后的个人建议从能跑到好用6.1 生产环境部署形态与脚本化如果你只是本地学习java -jar直接跑没什么问题。但如果是生产环境建议用 systemd 管理服务同时配合 Kafka 做消息队列。我在实际使用中是这样处理的写一个简单的.service文件注册成系统服务设置Restartalways这样即使进程意外退出也能自动拉起。生产部署还有一个比 jar 裸跑更合适的方案把编译出的 boot jar 做成 Docker 镜像。ThingsBoard 源码仓库里自带 Dockerfile 模板基于官方的基础镜像把 jar 和配置目录挂载进去就行。这样做的好处是迁移方便而且日志可以统一收集。6.2 二次开发时的模块边界认知源码编译完成后最值钱的是你对整个平台模块的理解。ThingsBoard 的代码结构大致分为四块application是整体启动入口common是公共工具和抽象模型dao是数据库操作层rule-engine是规则引擎核心。做二次开发时按照这个边界去定位问题会非常高效。我这次改造租户隔离逻辑主要动了application和dao两个模块。改完之后重新执行mvn install -DskipTests因为只编译了部分模块整个过程比全量编译快很多。有人会问需不需要每次重新编译前端如果只改后端逻辑前端静态资源没有变化就不需要重新执行npm run build直接启动后端 jar 即可。这也算是模块化解耦带来的一个好处。另外提一句如果你在 MQTT 设备接入侧做东西注意 ThingsBoard 的 transport 模块是独立打包的默认启动的 jar 已经包含 MQTT transport 监听 1883 端口。用 MQTT.fx 或者其他工具上报数据时直接连 IP:1883 即可不需要额外配置。6.3 从实用角度的体会源码编译安装这件事第一次跑通的时候可能觉得过程漫长、坑又多但跑通之后你会对整个平台的运行机制有非常清晰的认识。以后遇到平台出问题我的思路是从启动日志开始定位先看 boot jar 是否加载了正确配置再看数据库连接和队列状态最后再判断是不是顶层业务逻辑出错。这套排查路径正是在源码编译过程中被一步步逼着建立起来的。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门