2. ThingsBoard架构总览

ThingsBoard 从部署形态上分为两种:单体(Monolithic)与微服务(Microservices)。二者共用同一套核心业务逻辑,差别在于进程边界、通信方式与扩展粒度。理解这一点,是后续做容量规划、选型和排障的基础。

一、单体与微服务:同一内核,两种进程边界

单体模式下,所有模块(设备接入、规则引擎、告警、REST API、UI 后端)运行在同一个 JVM 进程内,模块之间是方法调用,没有网络开销。微服务模式下,这些模块被拆成独立服务,各自独立进程、独立部署,模块之间通过消息队列或gRPC通信。

关键差异不在功能,而在三处:通信成本(本地调用 vs 网络+序列化)、扩展粒度(整体扩容 vs 按服务扩容)、故障域(一处 OOM 拖垮全部 vs 单服务隔离)。单体适合中小规模、快速验证;微服务适合大规模设备接入、需要按接入/规则/存储分别扩容的场景。

单体架构 单进程 · 方法调用 · 整体扩容 ThingsBoard 单进程 (JVM) 设备接入 MQTT / HTTP / CoAP 规则引擎 Actor 模型 REST API / UI 后端 Spring MVC 告警 / 通知 规则节点驱动 共享数据访问层 (DAO) 同一连接池 · 同一事务边界 PostgreSQL + 可选 Kafka 数据库为唯一强依赖 微服务架构 独立进程 · 消息队列 · 按服务扩容 服务集群 tb-core 设备/资产/租户管理 tb-rule-engine 规则执行 tb-transport MQTT/HTTP/CoAP tb-web-ui / tb-js 前端与执行器 Kafka 消息总线 服务间异步通信 · 削峰 · 解耦 PostgreSQL / Cassandra + Redis 按服务选择存储 拆分 解耦 单体:模块间方法调用,无网络开销;微服务:模块间经 Kafka/gRPC,可独立扩缩容与故障隔离

二、核心模块划分

无论哪种形态,ThingsBoard 的功能都落在以下模块中,微服务只是把它们拆成独立进程:

  • tb-transport:设备接入层,负责 MQTT、HTTP、CoAP、LwM2M 协议解析与设备认证,把上行数据转成统一内部消息。
  • tb-core:设备、资产、租户、客户、关系等实体的管理与查询,是元数据中心。
  • tb-rule-engine:规则链执行引擎,基于 Actor 模型,每个规则节点是一个 Actor,消息在节点间流转。
  • tb-web-ui / tb-js-executor:前端界面与 JS 脚本执行器(规则节点中的自定义脚本在此运行)。
  • tb-node(单体):上述模块合并为一个可执行 jar,通过配置开关决定启用哪些组件。

模块划分的核心原则是按数据流方向分层:接入层只做协议转换与鉴权,不碰业务规则;规则引擎只做消息处理,不直接访问设备元数据(通过 tb-core 的 RPC 获取);存储层按读写特征分离。

三、消息队列与数据库选型

消息队列在单体中可选,在微服务中必需。ThingsBoard 支持 Kafka、RabbitMQ、AWS SQS 等,生产环境首选 Kafka,原因是分区有序、可重放、高吞吐。选型时关注三点:

  • 分区数:决定规则引擎并行度。分区数应 ≥ 规则引擎实例数,否则部分实例空闲。
  • 副本因子:生产环境至少 3,保证 broker 故障不丢消息。
  • 保留策略:按时间或大小,避免磁盘无限增长。

数据库分两类:关系型(PostgreSQL)存实体元数据、租户、规则链定义;时序型(Cassandra 或 PostgreSQL+TimescaleDB)存遥测数据。选型判断依据是写入速率与查询模式:

存储适用场景关键参数示例
PostgreSQL中小规模、实体关系复杂、需要事务连接池 20~50,shared_buffers 25% 内存
Cassandra高写入吞吐、时序数据、多节点线性扩展副本因子 3,一致性 QUORUM
Redis缓存设备状态、会话、规则引擎中间状态maxmemory-policy allkeys-lru
选型不是非此即彼:常见组合是 PostgreSQL 存元数据 + Cassandra 存遥测 + Redis 做缓存,三者各司其职。

四、水平扩展与高可用设计原则

水平扩展的前提是无状态化。ThingsBoard 的 tb-core、tb-rule-engine、tb-transport 都是无状态服务,可以任意增加实例,通过 Kafka 分区或负载均衡分发请求。有状态的部分只有数据库和消息队列,它们靠自身集群机制保证高可用。

具体扩展策略:

  1. 接入层扩展:增加 tb-transport 实例,前置负载均衡(如 HAProxy/Nginx)按连接数分发。MQTT 长连接需注意会话保持。
  2. 规则引擎扩展:增加 tb-rule-engine 实例,Kafka 分区自动重新分配,每个分区同一时刻只被一个实例消费,保证消息不重复处理。
  3. 数据库扩展:PostgreSQL 读写分离或分库;Cassandra 增加节点自动再平衡。
  4. 高可用:每个服务至少 2 实例,跨可用区部署;Kafka 副本因子 ≥ 3;数据库主从+自动故障转移。
常见误区:只增加 tb-rule-engine 实例但 Kafka 分区数不变,新增实例会因无分区可消费而空闲。扩展规则引擎前,先确认分区数是否足够。

一个可参考的容量估算示例(假设值,非实测):若单设备平均 1 条/秒遥测,10 万设备即 10 万条/秒。按 Kafka 单分区约 1~2 万条/秒估算,至少需要 6~10 个分区;若每个规则引擎实例处理 2 个分区,则需 3~5 个实例。实际值需压测确认,此处仅作规划起点。

总结:单体与微服务的选择取决于规模与运维能力;核心模块按数据流分层;消息队列在微服务中不可省略,Kafka 是首选;数据库按元数据与时序数据分离选型;水平扩展的前提是无状态化与分区数匹配,高可用靠多实例、多副本、跨区部署共同保证。