2. 环境准备

ThingsBoard 作为一款基于 Java 与 Netty 构建的开源物联网平台,其核心服务(Transport、Rule Engine、Web UI)对底层运行环境有明确的版本依赖。版本选择错误或组件缺失,往往会导致编译失败、数据库连接异常、前端构建报错等连锁问题。本章将系统梳理 ThingsBoard 二次开发所需的全部基础依赖,给出经过验证的版本组合,并演示从零搭建可运行开发环境的完整步骤。下图展示了 ThingsBoard 开发环境的整体组件拓扑与数据流关系,帮助你在动手安装前建立全局认知。

ThingsBoard 开发环境组件拓扑与数据流 客户端接入层 HTTP / MQTT / CoAP 设备模拟器 / Postman 浏览器 (Web UI) ThingsBoard 核心服务 TB-Transport (Netty) TB-RuleEngine TB-WebUI (Node.js) 数据存储层 PostgreSQL (实体) Cassandra (时序) Redis (缓存/会话) 基础设施 Docker Engine JDK 17 (LTS) Maven 3.8+ 开发工具链(宿主机) IntelliJ IDEA VS Code Git Postman / MQTTX DBeaver / pgAdmin Java 代码调试 前端 TypeScript 版本管理 接口测试 数据库管理 推荐版本组合(ThingsBoard 3.6.x) JDK 17.0.9+ Node.js 18.18+ PostgreSQL 14.x Cassandra 4.1.x Docker 24+ 注:实际版本以官方 pom.xml 和 package.json 为准

上图清晰地展示了 ThingsBoard 运行时各组件之间的协作关系:设备通过 MQTT/HTTP 接入传输服务,规则引擎处理数据并写入 PostgreSQL(实体数据)与 Cassandra(时序数据),Web UI 通过 REST API 与后端交互。开发者在宿主机上使用 IDE 编写代码,通过 Docker 管理中间件,最终将编译产物部署到本地或远程环境。理解这张拓扑图,有助于你在后续安装过程中明确每个组件的作用边界。

2.1 核心依赖版本选择与安装

2.1.1 JDK 版本选择与配置

核心原理:ThingsBoard 3.x 系列基于 Spring Boot 2.7 与 Java 17 构建,官方 CI 使用 JDK 17 进行编译与测试。JDK 版本过低会导致 Lambda 表达式、Records、Switch 表达式等语法无法编译;版本过高(如 JDK 21)虽然兼容,但可能触发某些第三方库的反射警告或模块化限制。

判断方法:打开 ThingsBoard 源码根目录下的 pom.xml,查看 <java.version> 标签。3.6.x 版本通常为 17。同时检查 maven-compiler-plugin 的 release 参数,确保与本地 JDK 一致。

推荐安装:使用 Eclipse Temurin JDK 17.0.9+(Adoptium 发行版),避免使用 OpenJDK 早期版本或 Oracle JDK 的旧版本。安装后设置环境变量:
# Linux / macOS (bash/zsh)
export JAVA_HOME=/usr/lib/jvm/temurin-17
export PATH=$JAVA_HOME/bin:$PATH

# Windows (PowerShell)
$env:JAVA_HOME = "C:\Program Files\Eclipse Adoptium\jdk-17.0.9"
$env:Path = "$env:JAVA_HOME\bin;$env:Path"

验证:执行 java -version 应输出 openjdk version "17.0.9" 或更高。若同时安装了多个 JDK,务必确认 IDE 与 Maven 使用的均为 JDK 17。

常见误区:不要使用 JDK 8 或 JDK 11 尝试编译 ThingsBoard 3.6+,即使通过修改 pom.xml 强行降级,也会在运行时遇到 UnsupportedClassVersionError 或 Netty 的 NoSuchMethodError。此外,避免使用 JRE 替代 JDK,因为编译过程需要 javac 工具。

2.1.2 Node.js 与前端构建环境

核心原理:ThingsBoard 的 Web UI 模块(ui-ngx)基于 Angular 15 开发,构建工具为 npm。Node.js 的版本直接影响 Angular CLI 的兼容性。Node.js 18 是 Angular 15 的官方支持版本,Node.js 20 也可用,但 Node.js 16 及以下版本会因缺少 fetch 或 crypto 模块而构建失败。

判断方法:查看 ui-ngx/package.json 中的 engines 字段(如果存在),或参考 Angular 官方兼容性表。通常要求 Node.js ≥ 18.10。

安装步骤:

  1. 从 Node.js 官网下载 LTS 版本(18.x 或 20.x),推荐使用 nvm(Node Version Manager)管理多版本。
  2. 安装后执行 node -v 与 npm -v 确认版本。
  3. 设置 npm 镜像(国内用户建议):
    npm config set registry https://registry.npmmirror.com
经验提醒:前端构建非常消耗内存,建议 Node.js 进程的堆内存至少 4GB。可在 package.json 的 scripts 中增加 "build": "node --max_old_space_size=4096 node_modules/@angular/cli/bin/ng build" 来避免内存溢出。

2.1.3 PostgreSQL 与 Cassandra 安装

核心原理:ThingsBoard 使用 PostgreSQL 存储实体数据(设备、租户、规则链、用户等),使用 Cassandra 存储时序数据(遥测、事件)。两者缺一不可,但可以通过 Docker 快速部署,避免污染宿主机环境。

版本选择:

数据库推荐版本说明
PostgreSQL14.x / 15.x3.6.x 官方默认使用 14,15 也可用;需启用 pgcrypto 扩展
Cassandra4.1.x3.6.x 官方使用 4.1,3.11 已不再推荐;需配置数据目录与 JVM 堆内存

Docker 快速部署:

# PostgreSQL
docker run -d --name tb-postgres \
  -e POSTGRES_DB=thingsboard \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=postgres \
  -p 5432:5432 \
  postgres:14

# Cassandra
docker run -d --name tb-cassandra \
  -e CASSANDRA_CLUSTER_NAME="ThingsBoard Cluster" \
  -e CASSANDRA_DC="dc1" \
  -e CASSANDRA_RACK="rack1" \
  -p 9042:9042 \
  cassandra:4.1
风险提示:Cassandra 默认需要 2GB 以上堆内存,若宿主机内存不足,可添加 -e MAX_HEAP_SIZE=512M -e HEAP_NEWSIZE=128M 参数,但会降低写入性能。另外,PostgreSQL 的密码不要使用弱口令,否则在公网环境极易被攻击。

2.1.4 Docker 与容器化辅助工具

核心原理:Docker 不仅用于运行数据库,还可用于快速启动 ThingsBoard 的完整镜像进行功能验证。但二次开发时,我们通常只在 Docker 中运行中间件,而将 ThingsBoard 源码运行在宿主机 IDE 中,以便断点调试。

安装要求:Docker Engine 24+ 或 Docker Desktop 4.x。Linux 用户需配置 docker group 避免每次使用 sudo。同时建议安装 docker-compose 插件,用于编排多容器环境。

验证:执行 docker --version 与 docker compose version,确保输出正常。

2.2 开发环境搭建完整流程

2.2.1 源码获取与项目结构解析

操作流程:

  1. 从 GitHub 克隆 ThingsBoard 源码:
    git clone https://github.com/thingsboard/thingsboard.git
    cd thingsboard
  2. 切换到你需要的版本分支(例如 release-3.6):
    git checkout release-3.6
  3. 理解项目结构:
    • application/:主服务模块,包含启动类与配置
    • transport/:MQTT、HTTP、CoAP 传输模块
    • rule-engine/:规则引擎实现
    • ui-ngx/:Angular 前端工程
    • dao/:数据库访问层
案例拆解:假设你需要在本地修改规则引擎的某个节点逻辑。首先在 rule-engine 模块中找到对应的 Java 类,修改后通过 Maven 增量编译 mvn -pl rule-engine -am install -DskipTests,然后重启 application 模块。此时无需重新构建前端,因为规则引擎的改动不影响 REST API 接口。

2.2.2 数据库初始化与配置

核心原理:ThingsBoard 启动时会自动执行数据库 Schema 迁移(使用 Flyway),但需要手动创建数据库实例并设置正确的连接参数。

操作步骤:

  1. 创建 PostgreSQL 数据库:
    docker exec -it tb-postgres psql -U postgres -c "CREATE DATABASE thingsboard;"
  2. 修改 application/src/main/resources/thingsboard.yml 中的数据库连接:
    spring:
      datasource:
        url: jdbc:postgresql://localhost:5432/thingsboard
        username: postgres
        password: postgres
      cassandra:
        contact-points: localhost:9042
        keyspace-name: thingsboard
  3. 启动 Cassandra 并创建 Keyspace(首次启动会自动创建,但建议手动确认):
    docker exec -it tb-cassandra cqlsh -e "CREATE KEYSPACE IF NOT EXISTS thingsboard WITH replication = {'class':'SimpleStrategy','replication_factor':1};"
常见误区:不要使用 PostgreSQL 的默认数据库 postgres 作为 ThingsBoard 的数据库,否则 Flyway 迁移会与系统表冲突。另外,Cassandra 的 Keyspace 名称必须与配置一致,否则启动时抛出 InvalidQueryException。

2.2.3 后端编译与启动

操作流程:

  1. 在项目根目录执行 Maven 编译(跳过测试以节省时间):
    mvn clean install -DskipTests -Dlicense.skip=true
  2. 启动主应用(开发模式):
    cd application
    mvn spring-boot:run -Dspring-boot.run.profiles=dev
  3. 观察日志,等待 Started ThingsboardApplication 输出,表示启动成功。
经验提醒:首次编译需要下载大量依赖,建议配置 Maven 镜像(阿里云或华为云)。若编译过程中出现 license 相关错误,可添加 -Dlicense.skip=true 跳过许可证检查。

2.2.4 前端构建与联调

核心原理:前端开发服务器通过代理将 API 请求转发到后端,实现前后端分离调试。

操作步骤:

  1. 进入前端目录并安装依赖:
    cd ui-ngx
    npm install
  2. 启动 Angular 开发服务器:
    npm start
  3. 访问 http://localhost:4200,使用默认账号 sysadmin@thingsboard.org / sysadmin 登录。
案例拆解:假设你修改了前端某个仪表盘组件,但刷新页面后看不到效果。此时需要检查 Angular 开发服务器是否监听了文件变化。若使用 npm start 默认配置,热更新会自动生效;若使用 ng serve --prod 则不会。另外,若后端 API 地址不是 localhost:8080,需修改 ui-ngx/src/app/shared/config/app.config.ts 中的 apiUrl 属性。

2.3 环境验证与常见问题排查

2.3.1 验证清单

检查项命令/方法预期结果
JDK 版本java -version17.0.x
Node.js 版本node -vv18.x 或 v20.x
PostgreSQL 连接psql -h localhost -U postgres -c "SELECT 1;"返回 1
Cassandra 连接cqlsh localhost 9042 -e "DESCRIBE keyspaces;"包含 thingsboard
后端启动查看日志无 ERROR,端口 8080 监听
前端启动浏览器访问 4200登录页正常渲染

2.3.2 典型排障案例

场景:后端启动时报 Connection refused: localhost/127.0.0.1:9042。

分析:Cassandra 未启动或端口映射错误。执行 docker ps 检查容器状态,若容器已退出,查看日志 docker logs tb-cassandra,常见原因是内存不足导致 JVM 无法启动。

解决:增加 Docker 内存限制或降低 Cassandra 堆内存配置。修改后重启容器,并确认 docker exec -it tb-cassandra cqlsh 能正常连接。

总结复盘:环境准备阶段最容易出现的问题集中在版本不匹配与端口冲突。建议在开始任何代码修改前,先完整跑通一次官方默认环境的启动流程,确认基线可用。后续每次升级依赖版本时,务必回归测试数据库迁移与前端构建两个关键环节。