iii 核心架构解析:用 Worker、Function、Trigger 与 Engine 四要素构建跨语言实时系统
2026/9/13 18:04:24 网站建设 项目流程

iii 核心架构解析:用 Worker、Function、Trigger 与 Engine 四要素构建跨语言实时系统

【免费下载链接】iiiEffortlessly compose, extend, and observe every service in real-time for the first time ever.项目地址: https://gitcode.com/GitHub_Trending/mo/iii

本文以 iii 项目 0.13.0 文档版本中的 Understand iii 概览 为核心,完整讲解 iii 系统的四大组成——Worker(宿主)、Function(工作单元)、Trigger(触发源)、Engine(路由中枢)——并结合 Quickstart 教程 的真实操作与 Engine 协议源码 的实现细节,帮助你建立一套可落地的系统心智模型:读完后你将理解为什么任意语言、任意运行环境的 Worker 都能通过同一条 WebSocket 契约接入同一引擎,以及函数调用如何在不感知部署位置的前提下完成跨语言路由。

一个统一接口的思想

Unix 给进程提供了单一接口,React 给组件提供了单一接口。iii 的出发点类似:它给所有类别的软件——队列、调度器、Agent、前端、沙箱、业务逻辑——提供了一套单一接口:

  • Worker承载工作(host work);
  • Function就是工作本身;
  • Trigger决定工作在何时因何运行;
  • Engine负责在它们之间路由。

一旦建立这四个部件的心智模型,iii 中的一切其他概念都只是这一主题的变奏。

快速上手:四个部件的最小系统

Quickstart 教程是本文所有示例的基础。它最终构建出一个包含两个用户 Worker 连接同一 Engine 的运行时系统:

  1. math-worker是一个 Python Worker,注册math::add
  2. caller-worker是一个 TypeScript Worker,注册math::add_two_numbers,它通过 Engine 调用math::add

教程完成时,系统中还包含iii-stateiii-http两个 Worker、一个把math::add_two_numbers暴露在POST /math/add-two-numbers的 HTTP Trigger,以及一个名为math的键值作用域(其中保存running_total)。

运行时拓扑如下:

图中的每一条箭头都是 Worker 与 Engine 之间的 WebSocket 连接,不存在任何 Worker 到 Worker 的直连流量。当caller-worker调用math::add时,请求经由 Engine 转发:Engine 在自己的注册表中查出math::add的当前位置,再把调用路由到math-worker

从 Engine 的 README 与 Dockerfile 可以确认这两个端口的分工:49134是 Worker 连接的 WebSocket 端口,3111是 HTTP API 端口(iii-httpWorker 监听的正是后者)。

教程实操命令回顾

为让拓扑可复现,以下是 Quickstart 中对应的关键命令:

# 1. 创建跨语言脚手架 iii project init quickstart --template quickstart cd quickstart # 2. 启动引擎(监听 ws://localhost:49134) iii --config config.yaml # 3. 增量添加 Python Worker(注册 math::add) iii worker add ./workers/math-worker # 4. 增量添加 TypeScript Worker(注册 math::add_two_numbers) iii worker add ./workers/caller-worker # 5. 跨语言调用:TS Worker 经 Engine 调到 Python Worker iii trigger math::add_two_numbers a=10 b=20 # 输出: { "c": 30 } # 6. 追加状态能力与 HTTP 能力 iii worker add iii-state iii worker add iii-http

注意iii worker add的语义是向正在运行的系统增量添加 Worker,而不是重建系统——这是理解 iii「组合式扩展」的关键:加状态、加 HTTP 端点,都是对活体系统的热插拔。

Worker:任何能开 WebSocket 的程序

Worker 的定义非常宽泛:任何能连接到 Engine 并向其注册 Trigger 和 Function 的东西都是 Worker。Worker 可以跑在任何地方——笔记本、容器、浏览器标签页、microVM——用任何语言,只要它能向 Engine 打开一条 WebSocket。

Quickstart 中的两个 Worker 满足同一份契约:打开到 Engine 的 WebSocket 连接。连接建立后,它可以注册 Function、注册 Trigger、trigger()其他 Function。一个 Worker 通常会做其中至少一件事,但最终并不被要求做任何一件事。

Python 与 TypeScript 这两个 Worker 是相互独立的进程,语言不同、运行时不同,甚至可能不在同一台机器上。它们彼此不知道对方的执行上下文,它们只跟 Engine 说话,剩下的由 Engine 处理。

这就是「any language, any runtime」在实际中的含义:Worker 契约小到足以在任何支持 WebSocket 和 JSON 的语言中实现,而 Engine 对每个 Worker 一视同仁,无论它如何构建、在哪里运行。

从源码结构看,这条契约就是 engine/src/protocol.rs 中定义的Message枚举:RegisterFunctionRegisterTriggerRegisterTriggerType等都是线协议上的标准消息。engine/src/engine/mod.rs 中的RegisterFunctionRequest结构体进一步揭示了注册消息携带的完整元数据:

pub struct RegisterFunctionRequest { pub function_id: String, pub description: Option<String>, pub request_format: Option<Value>, pub response_format: Option<Value>, pub metadata: Option<Value>, }

也就是说,Worker 注册的不仅是一个函数名,还可以附带请求/响应的 JSON Schema(request_format/response_format)与描述信息——这正是 Console 等观察面能够展示函数签名与格式的前提。

进程隔离、连接生命周期等细节可进一步参考 Workers 概念页。

Trigger:三种发起调用的方式

一个 Trigger 由三部分组成:类型(type)、配置(configuration)、以及它所调用的函数 ID(function ID)。类型可以是 HTTP、cron、队列消息、状态变更、另一个 Function 调用trigger;配置则对应「哪条路径、哪个计划、哪个队列」。

Quickstart 中出现了三种触发方式:

1. CLI 触发。iii trigger math::add a=2 b=3本身就是由 CLI 发起的一个 Trigger,Engine 会把调用路由到当前提供math::add的 Worker。

2. SDK 调用。worker.trigger({ function_id: 'math::add', ... })是同一思想的另一版本:一个 Worker 内的某个 Function 发出 Trigger 去调用另一个 Function,经由 Engine 路由,与 CLI 路径完全对等。

以上两条路径无需注册显式 Trigger 就能作用于任何已注册的 Function:每一次registerFunction()都天然附带一个可用这两种方式调用的 Trigger。

3. HTTP Trigger。iii-httpWorker 通过worker.registerTrigger()注册的 HTTP Trigger 是最常见的响应式触发实现。以 Quickstart 中的POST /math/add-two-numbers为例,iii-http拥有 HTTP 套接字,请求到达后发生:

  1. iii-http查出匹配的 Trigger,发起一个以math::add_two_numbers(内部再打到math::add)为目标函数的请求;
  2. Engine 收到请求,把调用路由到caller-worker
  3. 响应沿原路返回。math::add这个 Function 从头到尾看不到任何 HTTP 请求——它看到的只是一个 payload,与其他任何调用无异。

在 Quickstart 教程 第 7 步中,这个注册长这样:

worker.registerTrigger({ type: "http", function_id: "http::add_two_numbers", config: { api_path: "/math/add-two-numbers", http_method: "POST" }, });

随后用curl -X POST http://localhost:3111/math/add-two-numbers -d '{"a": 100, "b": 200}'即可得到{ "c": 300, "running_total": 335 }——同一批函数在没有任何 handler 代码改动的情况下,同时响应iii trigger与 HTTP 请求。

此外,一个 Function 可以挂多个 Trigger:同一个函数既可由 cron 计划调用,也可由队列消息调用,还可被 CLI 直接调用。

触发器类型、调用模式(同步 vs fire-and-forget)、触发管线、生命周期与条件(conditions)等完整内容见 Triggers 概念页。

Function:稳定的命名工作单元

math::addmath::add_two_numbers都是 Function。其标识符遵循service::name惯例:math命名空间把相关函数聚在一起,名字则标识具体 handler。但分组是任意的——虽然推荐使用结构化的path::to::functions风格,iii 内部并不强制校验命名结构。

Function ID 在 Worker 重启前后保持稳定。当math-worker停止并重启后,调用方无需感知:它们继续调用math::add,Engine 会把调用路由到当前提供该 Function 的任意实例。这正是注册表模型的价值——调用方依赖的是逻辑名而非物理位置。

Function 是同步定义的,但得益于 Trigger 与 Function 之间的解耦,它可以被异步调用。标识符惯例、直接调用与「一个 Function 多个 Trigger」等细节见 Functions 概念页。

Python 侧的注册产物可以在教程的math-worker中看到——处理函数接收 dict 形式的 payload、返回 dict 结果,其中还通过worker.trigger({ "function_id": "state::get", ... })跨 Worker 访问状态,再次印证「一切调用都是对 Function ID 的调用」这一模型。

Engine:注册表、路由与拓扑变更

Engine 是单进程协调者,持有每一个已连接 Worker、每一个已注册 Function 与 Trigger 的注册表

  • Worker 连接时,Engine 记录它提供哪些 Function;
  • Worker 断开时,Engine 移除其 Function、取消这些 Function 的在途调用(in-flight invocations),并通知系统其余部分拓扑已变化。

从源码结构看,engine/src/protocol.rs 还揭示了注册协议中的命名空间(namespace)语义:消息可携带namespace字段,缺省时回落到DEFAULT_NAMESPACE(值为default),且 Engine 定义了FUNCTION_NAMESPACE_CONFLICT一类冲突码,用于在同一命名空间内拒绝重复导出的 function id——这说明「注册表」不仅是查找表,还是一份带冲突治理的注册中心。

路由独立于语言、运行时与位置。Engine 不需要知道math::add是跑在 Docker 里、树莓派上还是浏览器标签页里,它只需要知道某个Worker 提供它。同一份教程可以整体重新部署到不同的运行时组合上,而函数代码一行都不用改。

启动流程、配置热重载、实时注册表与发现面等机制详见 Engine 概念页。

小结:一个可以记住的模型

部件职责Quickstart 中的实例
Worker承载工作,连接 Enginemath-worker(Python)、caller-worker(TS)、iii-stateiii-http
Function命名的工作单元,payload 进、结果出math::addmath::add_two_numbers
Trigger让 Function 运行的原因与配置CLIiii triggerworker.trigger()、HTTP TriggerPOST /math/add-two-numbers
Engine注册表 + 路由中枢监听ws://localhost:49134的单进程

掌握这四个部件后,iii 的队列、调度、状态、HTTP、沙箱等能力都可以被理解为「不同 Trigger 类型 + 不同内置 Worker 的组合」。下一篇建议顺着 Understanding iii 目录 深入 Workers、Triggers、Functions 与 Engine 各自的专题页面,或回到 Quickstart 动手复现上述拓扑。

【免费下载链接】iiiEffortlessly compose, extend, and observe every service in real-time for the first time ever.项目地址: https://gitcode.com/GitHub_Trending/mo/iii

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询