Skip to content

ThingsBoard 的 Actor 系统如何初始化 ​

正文与配图来自原稿。接 Actor 模型:Actors 不是随便 new,而是通过 ActorSystem 创建;本文看 TB 启动时如何把系统拉起来。

1、概述 ​

ThingsBoard 使用 Actor 减轻多线程共享状态问题。Actor 通过 ActorSystem 创建。下面跟随启动流程看 Actor 如何初始化。

2、ThingsBoard 的 Actor 分类 ​

源码中可见多种 Actor,例如:

Actor 类型一览

常见包括:

Actor从类名可理解的职责方向
AppActor应用根 Actor
DeviceActor设备相关
RuleChainActor规则链
RuleNodeActor规则节点
StatsActor统计
TenantActor租户

具体行为以各类源码为准。

3、接口:TbActorSystem ​

系统侧定义接口 TbActorSystem,抽象 Actor 体系常用能力(创建 Actor、Dispatcher 等):

TbActorSystem 接口

4、默认实现:DefaultTbActorSystem ​

DefaultTbActorSystem 实现上述接口。内部用若干 ConcurrentHashMap 保存 ActorId、Mailbox、Dispatcher 等映射:

DefaultTbActorSystem

5、上下文:ActorSystemContext ​

初始化需要上下文 ActorSystemContext:一般由 Spring 创建 Bean,注入大量 Service / 组件,并带上 yml 中的配置项,供各 Actor 调业务能力:

ActorSystemContext

6、初始化入口:DefaultActorService ​

程序启动时,Actor 初始化从 DefaultActorService 开始:

DefaultActorService

其中 initActorSystem() 带 @PostConstruct。Spring Bean 生命周期大致为:

text
构造方法 → @Autowired 依赖注入 → @PostConstruct

接着创建 TbActorSystemSettings(线程池、Actor 初始化重试次数等):

TbActorSystemSettings

创建 Actor 系统:

java
system = new DefaultTbActorSystem(settings);

再用该 system 创建 Dispatcher(分配器):

创建 Dispatcher

跟进 createDispatcher:把 dispatcherId 与 Dispatcher 放入 map;Dispatcher 持有 executor(可理解为执行线程池):

createDispatcher

然后创建两个根 Actor:appActor 与 statsActor:

创建根 Actor

注意:这里拿到的通常是 TbActorRef,并不是直接 new AppActor() / new StatsActor() 的裸对象。创建时传入例如:

  • new AppActor.ActorCreator(actorContext)
  • new StatsActor.ActorCreator(actorContext, "StatsActor")

再把这两个 Actor 引用设回 ActorSystemContext,方便后续使用。至此系统骨架已起来。

进入:

java
appActor = system.createRootActor(
    APP_DISPATCHER_NAME,
    new AppActor.ActorCreator(actorContext)
);

最终落到 DefaultTbActorSystem#createActor:创建 TbActorMailbox,并与 actorId 一并放入 map:

createActor / Mailbox

调用 mailbox.initActor() → TbActorMailbox#initActor:

TbActorMailbox.initActor

此处的 dispatcher 来自构造:

java
new TbActorMailbox(this, settings, actorId, parentRef, actor, dispatcher);

再 tryInit(1)(尝试初始化一次),核心是:

java
actor.init(this);

即初始化具体 Actor(如 AppActor),把 TbActorCtx 赋上。传入的 this 是当前 TbActorMailbox,而 Mailbox 实现了 TbActorCtx:

TbActorCtx 相关 1

TbActorCtx 相关 2

statsActor 的初始化路径同理。


补充(辅) ​

text
DefaultActorService.@PostConstruct
  → new DefaultTbActorSystem(settings)
  → createDispatcher(...)
  → createRootActor(AppActor / StatsActor)
       → createActor → TbActorMailbox
       → mailbox.initActor → actor.init(mailbox as TbActorCtx)
  • 设备上线、规则链加载等会在后续由 App/Tenant 等 Actor 按消息再创建子 Actor,不单在启动时全部 new 完。
  • 读源码时以你分支的包名为准(org.thingsboard.server.actors 一带)。

相关文章 ​