ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

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

iii 核心架构解析:用 Worker、Function、Trigger 与 Engine 四要素构建跨语言实时系统 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 workFunction就是工作本身Trigger决定工作在何时因何运行Engine负责在它们之间路由。一旦建立这四个部件的心智模型iii 中的一切其他概念都只是这一主题的变奏。快速上手四个部件的最小系统Quickstart 教程是本文所有示例的基础。它最终构建出一个包含两个用户 Worker 连接同一 Engine 的运行时系统math-worker是一个 Python Worker注册math::addcaller-worker是一个 TypeScript Worker注册math::add_two_numbers它通过 Engine 调用math::add。教程完成时系统中还包含iii-state与iii-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 a10 b20 # 输出: { 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枚举RegisterFunction、RegisterTrigger、RegisterTriggerType等都是线协议上的标准消息。engine/src/engine/mod.rs 中的RegisterFunctionRequest结构体进一步揭示了注册消息携带的完整元数据pub struct RegisterFunctionRequest { pub function_id: String, pub description: OptionString, pub request_format: OptionValue, pub response_format: OptionValue, pub metadata: OptionValue, }也就是说Worker 注册的不仅是一个函数名还可以附带请求/响应的 JSON Schemarequest_format/response_format与描述信息——这正是 Console 等观察面能够展示函数签名与格式的前提。进程隔离、连接生命周期等细节可进一步参考 Workers 概念页。Trigger三种发起调用的方式一个 Trigger 由三部分组成类型type、配置configuration、以及它所调用的函数 IDfunction ID。类型可以是 HTTP、cron、队列消息、状态变更、另一个 Function 调用trigger配置则对应「哪条路径、哪个计划、哪个队列」。Quickstart 中出现了三种触发方式1. CLI 触发。iii trigger math::add a2 b3本身就是由 CLI 发起的一个 TriggerEngine 会把调用路由到当前提供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 套接字请求到达后发生iii-http查出匹配的 Trigger发起一个以math::add_two_numbers内部再打到math::add为目标函数的请求Engine 收到请求把调用路由到caller-worker响应沿原路返回。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::add与math::add_two_numbers都是 Function。其标识符遵循service::name惯例math命名空间把相关函数聚在一起名字则标识具体 handler。但分组是任意的——虽然推荐使用结构化的path::to::functions风格iii 内部并不强制校验命名结构。Function ID 在 Worker 重启前后保持稳定。当math-worker停止并重启后调用方无需感知它们继续调用math::addEngine 会把调用路由到当前提供该 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 记录它提供哪些 FunctionWorker 断开时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-workerPython、caller-workerTS、iii-state、iii-httpFunction命名的工作单元payload 进、结果出math::add、math::add_two_numbersTrigger让 Function 运行的原因与配置CLIiii trigger、worker.trigger()、HTTP TriggerPOST /math/add-two-numbersEngine注册表 路由中枢监听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),仅供参考
返回列表