news 2026/9/14 19:04:01

iii Workers 运维实战:基于 Compose 声明、添加与实时观测项目级 Workers

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
iii Workers 运维实战:基于 Compose 声明、添加与实时观测项目级 Workers

iii Workers 运维实战:基于 Compose 声明、添加与实时观测项目级 Workers

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

Workers 是 iii 系统中一切能力的载体:任何进程只要通过 WebSocket 连上引擎并注册函数与触发器,就成为可被整个系统路由调用的 worker。本文以官方 how-to 文档 docs/next/using-iii/workers.mdx 为骨架,围绕iii Compose讲解如何声明项目级 worker、从 registry 添加现成包、执行日常运维命令,并结合仓库内iii-compose的源码实现揭示身份命名空间、配置注入与生命周期背后的真实机制。读完你将能独立编写worker-compose.yaml、用iii trigger compose::*完成增删查改,并理解引擎与 worker 之间的连接模型。

Workers 的本质:连接、注册、断开即失效

文档开篇给出了 worker 的最小定义:

  • Workers 是通过WebSocket 连接 iii 引擎、并**注册函数(functions)和触发器类型(triggers)**的进程;
  • 一旦 worker 断开连接,它注册的函数与触发器立即停止可调用,直到它重新连接;
  • 引擎侧会为该连接自动做清理:函数和触发器从实时注册表中移除,正在执行中的调用被取消(返回invocation_stopped错误)。

这套"断开即失效"模型是理解整个 Compose 编排的前提:进程存活与网络连接是 worker 唯一且全部的存在依据,因此需要 Compose 这样的监督者来保障进程的拉起、重启与依赖顺序。worker 的具体连接方式(SDK 的registerWorker/register_worker/register_worker,以及III_URL约定)见 docs/next/creating-workers/workers.mdx,本文聚焦部署与运维侧。

Worker 身份与命名空间

身份是(namespace, name)二元组

一个 worker 的身份由(namespace, name)唯一确定:

  • 两个不同的命名空间可以使用相同的名字互不冲突;
  • 同一命名空间内,名字是独占的;
  • 当一个同名同命名空间的 worker 已经在线时,重复的 live owner 会被引擎以WORKER_NAMESPACE_CONFLICT拒绝。

这一"冲突即拒绝"的语义在技术规格 tech-specs/2026-07-14-worker-compose/namespace.md 中被明确为设计原则:命名空间是一个独立的运行时维度,而非函数重命名——state::get在任何地方都还是state::get,只是路由时多带一个命名空间参数,命中失败返回清晰的FUNCTION_NOT_FOUND并列出该函数实际存在的命名空间。冲突处理的完整错误码表格见 docs/next/using-iii/namespaces.mdx。

两个容易混淆的 namespace

原文档特意区分了两个 namespace 概念:

  • worker-compose.yaml顶层的namespace:字段:为该项目下所有容器(containers)选择命名空间;
  • Compose daemon 的--namespace(CLI 中写作-n):用于定位该 daemon 自己的compose::*控制面函数——它是操作者寻址到"众多 daemon 中那一个"的地址。

从源码看,cli.rs 中--namespace被声明为"该 daemon 应答compose::*的命名空间,并应用到其加载的每个项目;多个 daemon 可以挂到同一引擎,正是靠它区分彼此"。--up模式下省略该参数时,daemon 会继承初始 compose 文件中的命名空间,都没有时回落为default

SDK 侧的命名空间选择顺序

worker 实际注册到哪个命名空间,由 SDK 按以下优先级决定(详见 docs/next/using-iii/namespaces.mdx):

优先级来源
1SDK 中显式传入的namespace选项
2worker 进程环境变量III_NAMESPACE
3default(兜底)

浏览器 SDK 无法读取进程环境,只能显式传入。利用这一机制,同一份 worker 镜像可以通过按部署设置III_NAMESPACE来服务多租户。

用 Compose 声明项目 Workers

worker-compose.yaml的结构

项目级 worker 统一声明在worker-compose.yamlcontainers:之下,一个文件描述一个项目(原文档示例):

# namespace: default engine: workers: configuration: {} containers: state: worker: package://api.workers.iii.dev/state version: "0.22.2" config_name: state api: worker: path://./workers/api start_after: [state] scripts: run: pnpm start

关键规则:

  • package://(registry 包)必须给出显式的version,Compose 据此解析包图并写入锁文件;
  • path://(本地目录)的启动命令来自 compose 文件中的scripts.run,或者其iii.worker.yamlmanifest 中的scripts.start
  • start_after声明启动依赖,仅在同一文件内解析,形成启动 DAG。

启动一个项目

iii compose build --file worker-compose.yaml iii compose --namespace dev --up --file worker-compose.yaml
  • iii compose build在启动前下载所有声明的package://worker;--up随后复用共享的包缓存;本地path://worker 会被跳过(它们没有可下载的包);
  • 文件中出现engine:块时,daemon 会自己拥有并负责停止引擎;没有该块时,需通过--engine或环境变量III_URL连接一个由别处管理的引擎。

从源码看命令解析

cli.rs 定义默认文件名常量DEFAULT_COMPOSE_FILE = "worker-compose.yaml":不指定--file时直接使用当前目录下这个文件,因此在项目目录内运行无需再命名文件。同时注意:

  • --file仅在与--up一起使用时合法(requires = "up"),否则报FileRequiresUp错误;
  • iii compose build是唯一的纯本地动作:读取文件、准备 registry 包,不连接也不启动引擎;
  • --namespace在解析阶段即做校验(空串、含路径分隔符等都会被拒绝),因为它既是引擎路由的命名空间,又是~/.iii/compose下的目录名。

容器字段速查表

技术规格 tech-specs/2026-07-14-worker-compose/compose-file.md 给出了完整字段契约:

字段必填规则
workerpackage://(registry)或path://(本地目录)
version仅 package精确或范围版本,解析进 lockfile
start_after仅限同文件内的容器 id
config_name该容器拥有的配置条目名
config_override稀疏 map,合并覆盖拉取到的配置基值
scripts否(无 manifest 的path://必须提供run见下
working_dir默认:path://为 worker 目录,package://为 compose 文件目录

校验为硬错误:空containers、未知start_after、依赖环(报错会打印完整路径如api -> queue -> database -> api)、package://上写runpath://既无 manifest 又无run等都会被拒绝。iii compose validate可离线运行整套规则,无需引擎。

scripts钩子契约

同规格文档 tech-specs/2026-07-14-worker-compose/scripts.md 定义了三个钩子:

钩子是否阻塞触发时机失败后果
pre_start每次 spawn 前,配置解析后退出码非 0 或超时 → 容器failed,worker 不启动,up回滚本次操作
run受监督worker 进程本体崩溃 → 级联停止本地依赖者
post_runrun退出后恰好一次(任何退出路径)告警 +last_error记入 status,不阻塞拆除

pre_start_timeout默认60s;钩子在任何 worker 类型上都执行(运行在 daemon 所在主机),run只对path://有意义——package://二进制的启动是隐式的(以标准 CLI 契约--url --namespace --config执行解析产物)。path://的启动优先级为:compose 的run> manifest 的scripts.startprisma migrate这类项目级准备动作放在pre_start是规格明确推荐的用法。

添加 Registry Worker

compose::add是向运行中的 daemon 添加 worker 的唯一入口:它解析包依赖图、把精确版本写回 compose 文件、然后重启项目:

iii trigger -n dev compose::add worker=state iii trigger -n dev compose::add worker=queue@0.21.5
  • -n dev寻址 dev 命名空间下的 daemon(对应 daemon 的--namespace);
  • 当 daemon 的工作目录不是项目目录时,用file=/absolute/path/worker-compose.yaml指定文件;
  • 若添加的 registry 根包kind 为engine(引擎已内置供应的包),会被拒绝;
  • 从 daemon.rs 的实现注释可以看到,compose::add承诺"写入精确版本",因此不会留下"latest"这种不可复现的解析结果。

已发布的 worker 包可在官方 registry 索引中查找,添加前建议先查看包页面确认其 functions、triggers 与配置 schema。

运维 Workers:状态、日志、重启与下线

原文档给出了一套完整的运维命令集:

iii trigger -n dev compose::status file=worker-compose.yaml iii compose logs state --follow --namespace dev iii trigger -n dev compose::restart file=worker-compose.yaml worker=state iii trigger -n dev compose::update file=worker-compose.yaml worker=state iii trigger -n dev compose::down file=worker-compose.yaml

语义对照:

命令作用
compose::status进程归属、PID、最近一次 supervisor 错误
compose::restart worker=只重启一个容器
compose::update worker=编辑该 worker 的包 pin(版本锁定)并重启整个项目
compose::down逆依赖顺序停止容器
iii compose logs <worker> --follow实时查看原始 stdout/stderr

两类观测视图要区分开:

  • 引擎的实时连接视图:用engine::workers::listengine::workers::info,看的是"当前有哪些 worker 连着引擎";
  • 进程级视图:用compose::status,看的是"谁拥有这些进程、PID 是多少、最后一次 supervisor 错误是什么"。

从 cli.rs 可见iii compose logs还支持--tail(默认行数见 logs.rs 的DEFAULT_TAIL_LINES,且设有上限MAX_TAIL_LINES)、--stream(限定 stdout/stderr 某一流)等参数,日志通过已运行的 daemon 读取,worker 名省略时读取项目内全部 worker 的输出。

配置:默认值、条目与覆盖优先级

每个 worker 包都会携带默认配置。容器层有两个配置相关字段:

  • config_name:为该容器命名其对应的配置-worker 条目(即注册到configurationworker 下的条目 id);
  • config_override:在容器里就地覆盖具体配置值。

配置的最终生效优先级是:

package 默认值 < 已存储的配置条目值 < config_override

原文档示例:

containers: http: worker: package://api.workers.iii.dev/http version: "0.21.3" config_name: http config_override: host: 0.0.0.0 port: 3111

配置如何到达 worker:III_CONFIG/III_CONFIG_NAME

Compose 会把合并后的配置值通过III_CONFIG环境变量传给子进程,并在声明了config_name时把条目名发布到III_CONFIG_NAME。完整的配置体系(两层结构:config.yaml引导 seed 与configurationworker 的 schema 校验注册表)见 docs/next/using-iii/configuration.mdx。

从源码看,这是iii-compose精心设计的保留环境变量契约。spawn.rs 定义了 8 个保留键(III_URLIII_NAMESPACEIII_COMPOSE_NAMESPACEIII_COMPOSE_FILEIII_COMPOSE_DIRIII_CONFIGIII_CONFIG_NAMEIII_WORKER_NAME),用户在environment/env_file中声明这些键会在解析期被拒绝,而不是被静默覆盖;子进程环境是"宿主基线 + 用户 env + 保留契约"三层合并的结果(spawn_plan)。其中:

  • III_URL是 daemon 自己的连接,就绪观测也走它,因此一个容器指向别的引擎对 daemon 不可见;
  • III_NAMESPACEIII_WORKER_NAME是一对"就绪观测"键;
  • III_CONFIGIII_CONFIG_NAME是同一份交付的两半:合并值写入文件、条目发布到 configuration 注册表(configuration.rs 的模块注释说明 worker 只需凭III_CONFIG的文件路径读取,无需任何凭据去主动拉取配置)。

引擎托管的例外:哪些 worker 不能由项目声明

以下 worker始终由引擎拥有,不属于项目 containers:

  • configuration
  • iii-worker-manager
  • iii-http-functions
  • iii-stream
  • iii-sandbox

它们应当放在engine.workers下(受 Compose 管理时),或者——仅当外部 supervisor 拥有引擎时——放在引擎的config.yaml中。另有三个内部 worker 会被自动注入iii-engine-functionsiii-telemetryiii-observability,它们绝不能被添加为 Compose 的 package 根。

一个常见需求:要为不可信 worker 配置 RBAC 监听器,就在engine.workers(或直连引擎模式的config.yaml)中声明iii-worker-manager,其完整 schema 与命名空间级expose_functions规则见 docs/next/creating-workers/worker-manager.mdx。

Compose 之外的 Workers

Compose 并不是运行 worker 的唯一方式,它只是一个可选的进程监督者。对于由Kubernetes、systemd、其他主机SDK 驱动的开发命令管理的进程,只需要两样东西:

  1. 引擎 URL;
  2. 一个 worker 名(以及可选命名空间)。

一旦连接成功,它就参与同一个函数与触发器网络,与其他 worker 完全对等;Compose 只拥有它在文件中声明的那些进程。这正对应 docs/next/creating-workers/workers.mdx 中"连接字符串是 worker 与 iii 实例之间的唯一耦合"的说法——worker 进程可以部署在网络可达的任何位置,SDK 侧读取III_URL即可加入。

从旧版本迁移

0.23 版本移除了iii worker命令、worker::*控制面函数以及引擎侧的"项目 worker 自启动"能力。如果你有一个旧项目,在启动前请先按 upgrading 目录 中的迁移指南处理:旧项目的 worker 声明方式需要转换到worker-compose.yaml+ Compose daemon 的模型上来,否则引擎不会再替你拉起这些进程。

编写 Worker:从部署回到开发

部署与运维解决的是"进程如何活着",而"worker 里装了什么"由 SDK 代码与 manifest 决定,入口统一在 docs/next/creating-workers/workers.mdx。该文档覆盖:SDK 连接代码(III_URL约定、namespace选项)、iii.worker.yamlmanifest、函数与触发器注册、以及发布流程。几个与本文直接相关的要点:

  • manifest:项目根目录的iii.worker.yaml声明name、可选description(一行人/LLM 可读摘要)与scripts.start;Compose 容器可用自己的scripts.run覆盖之,并用pre_run/post_run做生命周期钩子;
  • 生命周期状态connecting → connected → available / busy → disconnectedengine::workers::list等发现函数把拓扑变化暴露给系统其余部分;
  • 断线处理:调用方应捕获invocation_stopped(视为取消,重试需等 worker 重连);需要感知拓扑变化时可绑定engine::workers-available/engine::functions-available触发器;
  • 优雅关闭:SDK 的shutdown会干净地关闭 WebSocket,引擎随之移除注册、触发worker_disconnected事件并取消在途调用——特别适合一次性(one-shot / ephemeral)worker,如 Kubernetes Job、serverless 容器或定时脚本。

小结

把本文的运维命令与 docs/next/using-iii/configuration.mdx、docs/next/using-iii/namespaces.mdx 两篇配合使用,即可完整覆盖"声明 → 添加 → 配置 → 观测 → 下线"的项目级 worker 全生命周期。其背后的实现证据可以在 crates/iii-compose/src/cli.rs、crates/iii-compose/src/spawn.rs、crates/iii-compose/src/daemon.rs 以及 tech-specs/2026-07-14-worker-compose/ 系列规格中逐一核对。

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 19:03:29

ArmorPaint免费开源PBR贴图工具:从节点材质到游戏引擎全流程实战

如果你做3D资产做到一半&#xff0c;大概率会被贴图这一步卡得头皮发麻。建模再苦&#xff0c;至少每一步都是可控的&#xff0c;但一到上材质、出磨损、做旧化&#xff0c;大家默认就打开Substance Painter——然后就被授权费劝退。ArmorPaint这个名字&#xff0c;是我在一次游…

作者头像 李华
网站建设 2026/9/14 19:02:38

Deepseek技术发展与应用场景探索解析

读研/做科研&#xff0c;最忌讳“囤工具”——下载一堆软件&#xff0c;每款都浅尝辄止&#xff0c;反而浪费时间、拖慢效率。 这篇不贪多&#xff0c;只推荐4款「文献-数据-写作」全流程核心工具&#xff0c;每款都精细化拆解操作步骤、适配场景、避坑细节&#xff0c;甚至补…

作者头像 李华
网站建设 2026/9/14 19:00:28

Python+Django+MySQL从零搭建学生成绩管理系统(含安装教程)

简介&#xff1a;基于Python Django、MySQL与HTML技术栈构建的学生成绩管理系统&#xff0c;是一套面向Web开发初学者、课程设计与毕业设计场景的完整项目&#xff0c;能够帮助学习者快速了解Django项目从结构搭建到功能落地的过程。压缩包共373个文件&#xff0c;大小约2.58MB…

作者头像 李华
网站建设 2026/9/14 19:00:03

OpenClaw 跑 Skills 和 Agent 编排:Key 用 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 19:00:03

前端工程师的 AI 时代生存指南

2026 年中&#xff0c;很多前端工程师的工作流已经变成这样&#xff1a;需求进来&#xff0c;写 prompt&#xff0c;AI 生成代码&#xff0c;跑一遍能跑就行&#xff0c;不行就调 prompt 再来。diff 不细看&#xff0c;review 让 AI 做&#xff0c;只要达到需求&#xff0c;细节…

作者头像 李华
网站建设 2026/9/14 19:00:00

选对网络插件:kubeasz 集群跨节点通信提速避坑指南

选对网络插件&#xff1a;kubeasz 集群跨节点通信提速避坑指南 【免费下载链接】kubeasz 使用Ansible脚本安装K8S集群&#xff0c;介绍组件交互原理&#xff0c;方便直接&#xff0c;不受国内网络环境影响 项目地址: https://gitcode.com/GitHub_Trending/ku/kubeasz 业…

作者头像 李华