iii 引擎实战指南:从 Function/Trigger/Worker 三大原语到安装、配置与 WebSocket 协议
2026/9/15 1:36:19 网站建设 项目流程

iii 引擎实战指南:从 Function/Trigger/Worker 三大原语到安装、配置与 WebSocket 协议

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

本指南以仓库 engine/README.md 为主线,深入讲解 iii 引擎的核心抽象、安装启动、配置文件、Docker 部署、端口与 WebSocket 协议,并结合 engine/src 目录下的 Rust 源码(CLI 入口、引擎内核、协议定义、安全配置)进行源码级佐证。读完本文,你将掌握 iii 引擎从零启动到生产部署的完整路径,并理解引擎与 SDK Worker 之间基于 JSON 消息的调用协议。

引擎定位:基于三大原语的实时编排系统

iii 引擎(engine)是一个提供**持久化编排(durable orchestration)、跨语言互操作执行(interoperable cross-language execution)、功能实时发现(live discovery of functionality)、系统实时可扩展(live system extensibility)与系统实时可观测(live system observability)**的进程通信引擎。它只依赖三个简单原语即可组合出完整系统:

  • Function(函数):可被调用、可被发现的最小执行单元。SDK Worker 通过 WebSocket 向引擎注册函数,引擎维护全局函数注册表(FunctionsRegistry),并按(namespace, function_id)路由调用。
  • Trigger(触发器):把外部事件(HTTP 请求、定时任务、队列消息、状态变更等)绑定到函数上的机制。引擎维护触发器注册表(TriggerRegistry),事件到达时驱动目标函数执行。
  • Worker(工作进程):承载函数与触发器的运行时进程。可以是 Node.js、Python、Rust 等任意语言的 SDK 进程,通过 WebSocket 长连接接入引擎;也可以是引擎内置的模块 Worker(API、队列、流、可观测性等)。

从源码结构看,引擎内核将这三类原语的注册与路由集中管理:engine/src/engine/mod.rs 中的Engine结构体同时持有worker_registryfunctionsFunctionsRegistry)、trigger_registryTriggerRegistry)、service_registryServicesRegistry)与invocationsInvocationHandler)等核心注册表,所有 Worker 连接和函数调用都汇聚于此,构成一个"请求进入 → 路由到 Worker → 响应返回"的实时路由器。

安装 iii 引擎与版本验证

README 提供了一条官方一键安装命令:

curl -fsSL https://install.iii.dev/iii/main/install.sh | sh

该命令安装的是包含全部 CLI 命令的 iii 引擎二进制(engine 与 CLI 是同一个iii二进制)。仓库内同时保留了安装脚本本体,可查阅 engine/install.sh 了解其实现逻辑。

自定义安装目录或锁定版本

覆盖安装目录或锁定版本

指定安装到$HOME/.local/bin

curl -fsSL https://install.iii.dev/iii/main/install.sh | BIN_DIR=$HOME/.local/bin sh

锁定具体版本(例如 v0.11.3):

curl -fsSL https://install.iii.dev/iii/main/install.sh | sh -s -- v0.11.3

验证安装

command -v iii && iii --version

iii --version会打印CARGO_PKG_VERSION(见 engine/src/main.rs)。该文件是整个 CLI 的入口(iii二进制),基于 clap 解析子命令,并支持--config <path>--version--no-update-check等全局参数。

启动引擎:默认模式、配置文件与 Console

直接启动

README 记载了iii --use-default-config的启动方式,但需要说明的是:该标志在当前仓库源码中已被移除main.rs的单元测试use_default_config_is_no_longer_a_flag明确断言--use-default-config不再可解析(engine/src/main.rs),其职责由"iii在缺少config.yaml时自动创建"取代。因此当前版本直接运行:

iii

不带任何子命令时,CLI 进入 serve 模式启动引擎(run_serve,见 engine/src/main.rs)。启动流程为:

  1. 计算配置文件路径:显式--config优先,否则默认config.yaml
  2. 若文件不存在,交互式终端会询问"是否创建"(避免在错误目录静默写入);容器/CI 等非交互会话则自动创建,写入一个空workers:列表的起始配置(EngineConfig::starter_config_yaml(),见ensure_config_file);
  3. 加载配置、初始化日志,通过EngineBuilder构建引擎并serve()

该行为与文档 docs/using-iii/engine.mdx 一致:引擎自带 WebSocket 监听、配置 Worker 与可观测性等内部服务,其余能力通过iii worker add <name>按需开启。

使用项目配置文件

项目化部署时,在工作目录创建config.yaml,或显式指定路径:

iii --config /path/to/config.yaml

如果偏好自定义文件名(例如iii-config.yaml),显式传入即可:

iii --config /path/to/iii-config.yaml

打开控制台

iii console

引擎启动后运行在ws://localhost:49134,HTTP API 位于http://localhost:3111iii console会拉起 Web 控制台(其前端工程位于 console/packages/console-frontend),用于实时观察函数、触发器和调用链路。

引擎即路由器:config.yaml 配置深度解析

iii 引擎从项目根目录的config.yaml启动,配置结构非常收敛:顶层只有一个workers:键,列出引擎需要加载的 Worker(docs/using-iii/engine.mdx 称其为"first-boot seed"——首次启动种子配置)。

仓库自带的示例配置 engine/config.yaml 展示了完整形态:

registration_namespace_grace_ms: 5000 # Only workers that are part of the engine lifecycle belong here. Project # workers such as http, state, cron, queue, pubsub, and bridge belong in # worker-compose.yaml. workers: - name: iii-stream config: port: ${STREAM_PORT:3112} host: 127.0.0.1 adapter: name: redis config: redis_url: redis://localhost:6379 - name: configuration config: adapter: name: fs config: directory: ./config ttl_seconds: 0 # Ephemeral sandboxes are an engine-managed exception to worker-compose. # - name: iii-sandbox # config: # auto_install: true # image_allowlist: # - python # - node # default_idle_timeout_secs: 300 # max_concurrent_sandboxes: 32 # default_cpus: 1 # default_memory_mb: 512

要点解读:

  • workers:列表:每个条目有name(注册表 slug 或本地 Worker 名)和可选的config块。config块只在该 Worker 首次启动时被读取一次,作为配置种子写入配置存储;此后配置以"每个 Worker 一个文件"的形式存放在./config/下,支持从磁盘、Console 或configuration::set实时修改,引擎会把已消费的config:块从config.yaml中移除并留下注释。
  • registration_namespace_grace_ms: 5000:全局配置,控制 Worker 连接在命名空间确定前的注册缓冲宽限期(默认 5 秒)。引擎内核通过III_NAMESPACE_GRACE_MS环境变量优先、其次是该配置、最后回退 5 秒默认值来解析(见 engine/src/engine/mod.rs)。宽限期内,命名空间相关的注册消息(RegisterFunctionRegisterTrigger等)会被排队缓冲,等待engine::workers::register调用确定连接命名空间后再按到达顺序落位,避免注册被错误归入default命名空间。
  • iii-stream:流模块 Worker,监听端口支持${STREAM_PORT:3112}环境变量展开,默认 3112;其 Redis 适配器对应 engine/src/workers/stream/adapters 下的适配器实现。
  • configuration:配置 Worker,使用文件系统适配器(directory: ./config),ttl_seconds: 0表示条目不过期。
  • 注释中的iii-sandbox展示了临时沙箱的示例参数(镜像白名单、空闲超时、并发上限、CPU/内存配额),实际启用时按需取消注释。

环境变量展开

配置值支持${VAR:default}语法:读取环境变量VAR,未设置时回退到default。这允许在不拆分配置文件的前提下按环境切换端口、URL 与功能开关,且该语法同样适用于每个 Worker 的独立配置文件:

workers: - name: http config: port: ${HTTP_PORT:3111} host: ${HTTP_HOST:127.0.0.1}

安全配置(HTTP 外部调用)

引擎对外部 HTTP 调用(如registerfunction中的invocation指向外部 Lambda/HTTP 端点)有独立的安全策略,定义于 engine/src/config/mod.rs 的SecurityConfig

字段默认值说明
url_allowlist["*"](空则视为*URL 白名单,仅允许调用列表内的地址
block_private_ipstrue阻止调用私网 IP(SSRF 防护)
require_httpstrue强制要求 HTTPS 端点

配置采用deny_unknown_fields严格解析,未知字段会导致加载失败(见 engine/src/config/mod.rs 的测试)。该配置最终转换为UrlValidatorConfig,供调用校验器在每次外部调用前检查目标 URL。

Docker 部署:基础镜像、生产加固与 Compose 全家桶

拉取并运行镜像

docker pull iiidev/iii:latest docker run -p 3111:3111 -p 49134:49134 \ -v ./iii-config.yaml:/app/iii-config.yaml:ro \ iiidev/iii:latest

镜像的默认启动命令是["/app/iii", "--config", "/app/config.yaml"](见 engine/Dockerfile):容器内WORKDIR /appconfig.yaml挂载为只读。

生产加固示例

docker run --read-only --tmpfs /tmp \ --cap-drop=ALL --cap-add=NET_BIND_SERVICE \ --security-opt=no-new-privileges:true \ -v ./iii-config.yaml:/app/iii-config.yaml:ro \ -p 3111:3111 -p 49134:49134 -p 3112:3112 -p 9464:9464 \ iiidev/iii:latest

该命令体现了镜像的安全设计:只读根文件系统 +/tmp临时挂载、丢弃全部 Linux capabilities 仅保留NET_BIND_SERVICE(绑定 80/443 等低端口)、禁止提权。Dockerfile 基于gcr.io/distroless/cc-debian12:nonroot构建,以 UID 65532 的非 root 用户运行、无 shell,且预创建了/app/config/app/data目录并设置属主,保证配置 Worker 能落盘。CI 中还包含 Trivy 漏洞扫描、SBOM 物料清单证明与构建来源证明(build provenance)。

Docker Compose:Redis + RabbitMQ 全家桶

仓库提供了完整编排文件 engine/docker-compose.yml:

docker compose up -d

该栈包含三个服务:iii(映射 49134/3111/3112/9464 四个端口,设置RUST_LOG=infoIII_EXECUTION_CONTEXT=docker,依赖 Redis 与 RabbitMQ 健康检查通过后启动)、redis:7-alpine(队列/流模块的存储后端,带redis-cli ping健康检查)、rabbitmq:3-management-alpine(队列模块的 AMQP 后端,默认凭据guest/guest,生产环境请用.env覆盖)。

Docker Compose + Caddy(TLS 反向代理)

docker compose -f docker-compose.prod.yml up -d

engine/docker-compose.prod.yml 引入了 Caddy 2 作为 TLS 反向代理,并通过iii compose --namespace production --up --file /app/worker-compose.yaml以 worker-compose 方式启动项目(含nc -z 127.0.0.1 3111健康检查)。配套的 engine/Caddyfile 展示了端口到路径的路由映射:

your-domain.com { handle /api/* { reverse_proxy iii:3111 } handle /streams/* { reverse_proxy iii:3112 } handle /ws { reverse_proxy iii:49134 } handle { reverse_proxy iii:3111 } }

即:/api/*走 HTTP API、/streams/*走流 API、/ws走 WebSocket、其余兜底回 HTTP API。TLS 证书的申请与续期由 Caddy 自动完成。

端口一览与网络拓扑

端口服务
49134WebSocket(Worker 连接)
3111HTTP API
3112Stream API
9464Prometheus metrics
  • 49134是 SDK Worker 接入引擎的长连接端口,承载 JSON 协议消息与遥测帧(见下节)。
  • 3111提供 REST API,同时是 Console 的 HTTP 入口与iii triggerCLI 的调用目标。
  • 3112是流(Stream)通道 API,对应流模块 Worker 的默认端口(${STREAM_PORT:3112})。
  • 9464是 Prometheus 指标抓取端点,配合可观测性模块(engine/src/workers/observability)使用。

WebSocket 协议:消息类型与调用语义

引擎与 SDK Worker 之间通过 WebSocket 传输JSON 消息,协议 schema 完整定义在 engine/src/protocol.rs 的Message枚举中。README 列出的关键消息类型如下,括号内为协议字段名(serderename_all = "lowercase"):

消息方向作用
registerfunctionWorker → 引擎注册函数(含iddescriptionrequest_format/response_formatmetadata、可选的invocation外部 HTTP 引用)
invokefunction双向调用函数,携带invocation_idfunction_iddatatraceparent/baggage、可选的actionmetadatanamespace
invocationresult引擎 → Worker调用结果,携带invocation_idresulterrorErrorBodycode+message+ 可选stacktrace
registertriggerWorker → 引擎注册触发器(绑定trigger_typefunction_idconfig
unregistertriggerWorker → 引擎注销触发器
triggerregistrationresult引擎 → Worker触发器注册结果
registerserviceWorker → 引擎注册服务
functionsavailable引擎 → Worker函数可用性广播(实时发现机制)
ping/pong双向心跳保活

除此之外,协议还包含引擎在重连场景下使用的高级消息(engine/src/protocol.rs):

  • reattach:Worker 重连时携带previous_worker_idreattach_token(引擎在上一条连接上通过workerregistered下发的秘密),引擎据此退役旧连接、让注册重放落在干净状态上,避免与旧连接的清理流程竞争。
  • workerregistered:引擎确认 Worker 身份,并可附带reattach_token
  • registrationrejected:注册被拒绝(如WORKER_NAMESPACE_CONFLICT——同一命名空间已有同名存活 Worker;FUNCTION_NAMESPACE_CONFLICT——同一命名空间已有 Worker 导出该函数 id;INVALID_NAMESPACE——命名空间为空白)。

Fire-and-forget 语义

调用可以省略invocation_id实现即发即忘(fire-and-forget)。引擎内核对此有明确实现:InvokeFunction.invocation_idOption<Uuid>(engine/src/protocol.rs);spawn_invoke_function中,invocation_idSome时调用完成后回送InvocationResult,为None时则以后台任务方式执行且不回送结果(见 engine/src/engine/mod.rs)。TriggerAction枚举也与之呼应:{"type":"enqueue","queue":"..."}表示将调用转投队列,{"type":"void"}表示纯异步执行。

外部 HTTP 函数

registerfunction支持注册"外部函数"——引擎不经过本地 Worker,而是直接对invocation指定的 URL 发起 HTTP 调用。HttpInvocationRef(engine/src/protocol.rs)包含urlmethod(默认 POST)、timeout_msheadersauth(如 Bearer token 引用),协议测试中有完整的注册示例(external.my_lambda)。这类调用受前述SecurityConfig约束。

命名空间:显式路由维度

协议层面每个消息都可携带namespace字段,缺省时落入默认命名空间defaultDEFAULT_NAMESPACE,见 engine/src/protocol.rs)。引擎的函数解析策略是显式路由维度,不做跨命名空间搜索

Some(ns)只在ns中解析;None只在default中解析。不存在"就近匹配",调用方的命名空间不参与目标解析——analytics命名空间里的 Worker 若不显式指定命名空间,拿到的是default中的函数,而不是自己命名空间里的同名函数。

(见 engine/src/engine/mod.rs 中resolve_function的注释与实现。)这样做消除了"调用目标取决于谁在提问"的歧义:函数与 Worker 的注册表均以(namespace, id)为键,例如服务注册表ServicesRegistry就以(namespace, service_name)为键(engine/src/services.rs),保证多个项目在同一引擎上互不覆盖。若函数在目标命名空间缺失,引擎返回function_not_found错误码,并附带"该 id 实际存在于哪些命名空间"的提示。

可观测性:OTLP 帧与 Prometheus

除 JSON 协议消息外,WebSocket 连接还支持三类二进制遥测帧,通过魔数前缀区分(见 engine/src/engine/mod.rs):

前缀内容
OTLPTrace 追踪(OTLP JSON)
MTRCMetrics 指标(OTLP JSON)
LOGSLogs 日志(OTLP JSON)

SDK 直接将 OpenTelemetry 数据以带前缀的二进制帧推送给引擎,由handle_telemetry_frame分派到ingest_otlp_json/ingest_otlp_metrics/ingest_otlp_logs处理(engine/src/engine/mod.rs)。InvokeFunctionInvocationResult携带 W3Ctraceparent/baggage,实现跨 Worker、跨进程的分布式追踪上下文传播;指标则通过 9464 端口暴露给 Prometheus 抓取。README 提到"引擎内置 in-memory OpenTelemetry 配置,无需先创建 config.yaml 即可获得 traces/metrics/logs"——结合上文可知,当前版本中这一默认能力由引擎内置的可观测性服务承担,启动即具备。

仓库结构与源码导览

README 给出的仓库布局(当前仓库已将其中的src/modules/演进为src/workers/下的多个 Worker 目录):

  • engine/src/main.rs – CLI 入口(iii二进制):trigger(别名t)、consolecloudproject init/project generate-dockercomposeupdate等子命令,缺省为 serve 模式启动引擎;
  • engine/src/engine/mod.rs – 引擎内核:Worker 管理、函数/触发器/服务注册表、命名空间解析、调用生命周期(Engine结构体与EngineTrait);
  • engine/src/protocol.rs – WebSocket 消息 schema(Message枚举、ErrorBodyWorkerMetricsHttpInvocationRef);
  • engine/src/workers – 核心模块 Worker:http_functions(HTTP 函数)、queue(队列,含 Redis/RabbitMQ 等适配器)、stream(流,含适配器)、observability(可观测性:OTLP 导出、指标、追踪存储与 UI)、configuration(配置存储)、engine_fnworker等;
  • engine/config.yaml – 示例模块配置;
  • engine/examples/custom_queue_adapter.rs – 自定义模块与适配器示例;
  • engine/tests – 端到端测试集,例如cli_integration.rsconfiguration_e2e.rsqueue_e2e_happy_path.rsnamespace_routing_e2e.rsworker_ws_handshake_timeout_test.rs,覆盖 CLI、配置加载、队列、命名空间路由与 WebSocket 握手等行为。

各语言 SDK 位于 sdk/packages/node、sdk/packages/python、sdk/packages/rust,README 中的安装命令对应如下:

语言包名安装命令
Node.jsiii-sdkpnpm add iii-sdknpm install iii-sdk
Pythoniii-sdkpip install iii-sdk
Rustiii-sdkCargo.toml中添加依赖

本地开发与镜像构建

cargo run # 启动引擎 cargo run -- --config iii-config.yaml # 带配置启动 cargo fmt && cargo clippy -- -D warnings # 格式化与 Lint make watch # 监听模式(文件变更自动重编译)

本地构建 Docker 镜像

docker build -t iii:local . # 生产镜像(distroless) docker build -f Dockerfile.debug -t iii:debug . # 调试镜像(Debian + shell)

生产镜像的安全基线已在"生产加固"一节说明:distroless 无 shell 运行时、非 root 执行、CI 中的 Trivy 扫描、SBOM 证明与构建来源证明。

快速上手与后续阅读

  • 从零开始构建:参阅 docs/quickstart.mdx 与 docs/tutorials 下的分步教程;
  • 引擎配置详解:参阅 docs/using-iii/engine.mdx 与 docs/using-iii/configuration.mdx;
  • CLI 参考:参阅 docs/cli-reference/index.mdx;
  • 函数与触发器开发:参阅 docs/creating-workers 与 docs/using-iii/functions.mdx;
  • 多服务编排(worker-compose):参阅 crates/iii-compose 与 docs/upgrading。

许可证

iii 引擎采用 Elastic License 2.0(ELv2),同时包含专利声明(engine/PATENTS)与商标声明(engine/NOTICE),仓库根目录另有一份 SPDX 许可证清单 LICENSE.spdx。

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

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

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

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

立即咨询