Nova 是一个极简的 Serverless 平台,支持多种虚拟化后端(Firecracker microVM、Apple Virtualization.framework、Docker 等)实现函数级别的隔离执行。每次函数调用都运行在独立的轻量虚拟机或容器中,支持 Python、Go、Rust、WASM、Node.js、Ruby、Java、PHP、Deno、Bun、Lua 等 20+ 运行时。
后端已拆分为五平面架构(六个独立服务):
nova(控制平面)— 函数管理、配置、API Key、网关路由comet(隔离执行平面)— 执行器、VM/容器池化,提供 gRPCcorona(调度放置平面)— Cron 调度、自动扩缩nebula(事件摄入平面)— 事件总线、异步队列、工作流引擎aurora(可观测平面)— SLO 评估、Prometheus 指标zenith(网关)— 供 UI/MCP/CLI 统一接入
详细启动方式见 BACKEND_SPLIT.md。
用户 (CLI/HTTP) 宿主机 VM / 容器
| | |
|--- invoke hello --------> | |
| [1] 从 VM 池获取空闲 VM |
| (没有?创建新 VM) |
| | |
| [2] 启动 VM (Firecracker/Apple VZ/Docker)
| |---- vsock 连接 -----------> |
| | [3] agent 收到请求
| | 执行 /code/handler
| |<--- 返回 JSON 结果 ------ |
|<-- 输出结果 ----------- | |
| [4] VM 回到池中等待复用 |
| (60秒无调用则销毁) |
核心流程:
- 注册函数(名称、运行时、代码)到 Postgres
- 调用触发:从 VM 池获取或创建 VM(根据后端选择 Firecracker / Apple VZ / Docker)
- 宿主机通过 vsock 向 VM 内的 agent 发送执行指令
- agent 运行用户代码,返回 JSON 结果
- VM 保留在池中,60 秒内可复用(warm start),超时销毁
- 函数注册、更新、删除、查询
- 内联代码(
code字段)和文件路径(code_path)两种提交方式 - 多文件函数支持
- 函数版本管理(不可变快照)与别名(alias)路由
- 流量分割 / 金丝雀发布(
TrafficSplit)
- 编译型:Go、Rust、Zig、Swift、C、C++、Java、Kotlin、Scala、GraalVM、WASM
- 解释型:Python、Node.js、Ruby、PHP、Deno、Bun、Lua、Perl、R、Julia、Elixir
- 自定义运行时:
custom/provided(用户自带 bootstrap)
- Process 模式:每次调用 fork 新进程,隔离性强
- Persistent 模式:长驻进程复用连接,通过 stdin/stdout JSON 通信,适合高频调用
- 按函数维度池化 VM,空闲 TTL 自动回收(默认 60s)
- MinReplicas 预热,MaxReplicas 并发限制
- 实例级并发控制(
InstanceConcurrency) - Singleflight 去重,防止冷启动雷群效应
- 对冷启动 VM 创建 Firecracker 快照(state + memory)
- 后续冷启动从快照恢复,代码变更时自动使快照失效
- JWT + API Key 双认证模式
- RBAC 权限模型(角色 → 权限绑定 → 用户/租户)
- 多租户隔离(命名空间 + 配额)
- Secret 管理(AES-GCM 加密,
$SECRET:name引用注入环境变量) - 基于令牌桶的速率限制(多 Tier 支持)
- OpenTelemetry 分布式追踪(W3C Trace Context 穿透 VM 边界)
- Prometheus 指标导出(调用延迟直方图、冷启动计数等)
- 调用日志批量持久化(500ms / 100 条批次刷盘)
- 按小时时序聚合(24 桶滚动)
- SLO 策略评估(延迟/成功率/可用性阈值)
- 函数诊断 + AI 异常分析
- 调用热力图(按小时 × 按天分布)
- 成本追踪(函数级 + 全局汇总)
- 审计日志(API 操作自动记录)
- Cron 式定时调用(
@every、@hourly、@daily) - 按函数维度管理调度规则(创建、暂停、恢复、删除)
- 事件总线:Topic → Subscription → Delivery 三层模型
- 发布/订阅:创建 Topic 并发布事件,Subscription 自动将事件分发到目标函数
- 异步调用:
POST /functions/{name}/invoke-async入队异步执行 - DLQ(死信队列):失败超限自动进入死信队列,支持手动重试
- 幂等保证:基于 idempotency key 的精确一次语义
- Outbox 模式:事务性事件发布,保证与业务数据的一致性
- DAG 工作流定义(节点、边、条件分支)
- 工作流版本管理(不可变发布)
- 异步工作流运行与状态追踪
- 多事件源触发函数执行:Kafka、RabbitMQ、Redis Stream、Webhook、Filesystem
- 触发器状态管理(启用/禁用/健康状态)
- 自定义路由规则(路径 → 函数映射)
- 参数映射(header/query/path → event 字段)
- 路由级限流模板
- 跨函数共享运行时依赖(打包为 Layer)
- 函数可挂载多个 Layer,运行时自动合并到执行环境
- 为函数挂载持久化存储卷
- 支持数据跨调用保留
- 管理数据库连接资源(DSN、凭证策略)
- 函数绑定数据库资源,运行时自动注入连接信息
- 凭证轮换策略 + 访问日志审计
- 代码生成(
POST /ai/generate):根据描述自动生成函数代码 - 代码审查(
POST /ai/review):分析函数代码质量和安全性 - 代码重写(
POST /ai/rewrite):优化现有函数代码 - 诊断分析(
POST /ai/analyze-diagnostics):AI 分析函数运行异常 - 文档生成(
POST /ai/generate-docs):自动生成 API 文档 - 可配置 Prompt 模板
- 租户管理(创建、配额、命名空间隔离)
- RBAC 权限模型(角色 → 权限 → 用户绑定)
- 菜单/按钮级别的细粒度权限控制
- 多节点注册与心跳
- 健康节点发现
- 请求路由与放置调度
- 函数级成本计算(CPU 时间 × 内存 × 单价)
- 全局成本摘要
- 操作审计中间件,自动记录 API 调用
- 审计日志查询与详情
- 函数/工作流级 API 文档管理
- 文档分享(生成分享链接 + Token)
- 为函数定义测试用例集
- AI 辅助生成测试用例
- 基于 Next.js 16 + React 19 的 Web 管理控制台
- 国际化(i18n)支持:English、简体中文、繁體中文、日本語、Français
- 通过浏览器语言偏好自动检测,或通过头部工具栏切换语言
| 限制类型 | CLI 参数 | 默认值 | 说明 |
|---|---|---|---|
| vCPU | --vcpus |
1 | vCPU 数量 (1-32) |
| 内存 | --memory |
128 | 内存大小 (MB) |
| 执行超时 | --timeout |
30 | 超时 (秒) |
| 磁盘 IOPS | --disk-iops |
0 (无限) | 每秒操作数 |
| 磁盘带宽 | --disk-bandwidth |
0 (无限) | bytes/s |
| 网络入站 | --net-rx-bandwidth |
0 (无限) | bytes/s |
| 网络出站 | --net-tx-bandwidth |
0 (无限) | bytes/s |
系统按“接入层 -> 网关 -> 五平面 -> 执行后端 -> 存储”组织:
| 平面 | 服务 | 说明 | 入口 |
|---|---|---|---|
| Gateway | Zenith | 统一 HTTP 入口,转发到 Nova/Comet | cmd/zenith/ |
| Control Plane | Nova | 控制平面(函数、租户、配置、路由管理) | cmd/nova/ |
| Isolation & Execution | Comet | 隔离执行平面(执行器、池化),仅提供 gRPC | cmd/comet/ |
| Scheduler / Placement | Corona | 调度放置平面(Cron 调度、自动扩缩) | cmd/corona/ |
| Event Ingestion | Nebula | 事件摄入平面(事件总线、异步队列、工作流引擎) | cmd/nebula/ |
| Observability | Aurora | 可观测平面(SLO 评估、指标、输出捕获) | cmd/aurora/ |
| — | Agent | VM/容器内执行进程,负责运行用户函数 | cmd/agent/ |
| — | nova-vz | macOS VM 管理工具(Apple VZ, CGO) | cmd/nova-vz/ |
| — | Lumen / Atlas / Orbit | UI / MCP / CLI 调用方,统一访问 Zenith | lumen/ / atlas/ / orbit/ |
flowchart LR
subgraph "Clients"
lumen["Lumen (UI)"]
atlas["Atlas (MCP)"]
orbit["Orbit (CLI)"]
ext["External HTTP Clients"]
end
subgraph "Gateway Layer"
zenith["Zenith (HTTP Gateway)"]
end
subgraph "Control Plane"
nova["Nova (HTTP Control Plane)"]
compiler["Compiler / Function Service"]
end
subgraph "Isolation & Execution Plane"
comet["Comet (gRPC Execution)"]
executor["Executor"]
pool["Worker / VM Pool"]
end
subgraph "Scheduler / Placement Plane"
corona["Corona (Scheduler)"]
scheduler["Scheduler"]
autoscaler["Autoscaler"]
end
subgraph "Event Ingestion Plane"
nebula["Nebula (Event Ingestion)"]
asyncq["Async Queue Workers"]
eventbus["Event Bus Workers"]
workflow["Workflow Engine"]
end
subgraph "Observability Plane"
aurora["Aurora (Observability)"]
slo["SLO Evaluator"]
prom["Prometheus Metrics"]
end
subgraph "Runtime Backends"
fc["Firecracker Backend"]
applevz["Apple VZ Backend"]
docker["Docker Backend"]
agent["nova-agent (in VM/container)"]
assets["Rootfs / Code / Snapshot Assets"]
end
subgraph "State / Infra"
pg["PostgreSQL"]
end
lumen --> zenith
atlas --> zenith
orbit --> zenith
ext --> zenith
zenith -->|"HTTP management routes"| nova
zenith -->|"gRPC invoke/proxy routes"| comet
nova --> compiler
nova --> pg
comet --> executor
comet --> pg
corona -->|"gRPC invoke"| comet
corona --> scheduler
corona --> autoscaler
corona --> pg
nebula -->|"gRPC invoke"| comet
nebula --> asyncq
nebula --> eventbus
nebula --> workflow
nebula --> pg
aurora --> slo
aurora --> prom
aurora --> pg
executor --> pool
executor --> pg
pool --> fc
pool --> applevz
pool --> docker
fc --> agent
applevz --> agent
docker --> agent
fc --> assets
applevz --> assets
docker --> assets
客户端 HTTP 请求
|
v
API Server (:9000)
|-- 认证中间件 (JWT / API Key)
|-- 限流中间件 (Token Bucket)
|-- 追踪中间件 (OpenTelemetry)
|
v
Executor
|-- 加载函数元数据 + 代码 (Store)
|-- 解析 $SECRET: 引用 (Secrets Resolver)
|-- 获取 VM (Pool)
| |-- 命中暖池 -> 直接复用
| |-- 冷启动:
| | |-- 有快照 -> 恢复快照
| | |-- 无快照 -> 创建 VM
| | | |-- 分配 CID + IP
| | | |-- 创建 TAP 设备
| | | |-- 构建代码磁盘 (debugfs)
| | | |-- 启动 Firecracker 进程
| | | +-- 等待 Agent 就绪
| | +-- 发送 Init 消息
| +-- Singleflight 去重并发请求
|
v
Agent (VM 内, vsock:9999)
|-- 接收 Exec 消息
|-- Process 模式: fork 进程执行
|-- Persistent 模式: stdin/stdout JSON 交互
|-- 返回 Resp 消息 (output/error/duration)
|
v
Executor
|-- 记录指标 (Metrics)
|-- 批量写入调用日志 (Log Batcher -> Postgres)
|-- 归还 VM 到池(重置空闲计时器)
|
v
返回 InvokeResponse (output, error, duration_ms, cold_start)
cmd/{nova,comet,corona,nebula,aurora,zenith} (各服务入口)
|
+-- api/server
| |-- api/controlplane (函数 CRUD / 运行时 / 快照 / 配置 / 网关 / AI)
| +-- api/dataplane (调用 / 日志 / 指标 / 健康检查 / 异步)
|
+-- executor (调用编排)
| |-- store (元数据 + 代码)
| |-- pool (VM 池)
| |-- secrets (密钥解密)
| +-- metrics (指标采集)
|
+-- pool (VM 生命周期管理)
| +-- backend (抽象接口)
| |-- firecracker (microVM 后端)
| |-- applevz (Apple VZ 后端)
| +-- docker (容器后端)
|
+-- workflow (DAG 工作流引擎)
+-- eventbus (事件总线 / 发布订阅)
+-- asyncqueue (异步调用队列 + DLQ)
+-- triggers (外部事件源触发器)
+-- gateway (API 网关路由)
+-- layer (依赖层管理)
+-- volume (持久化卷)
+-- ai (AI 代码助手)
+-- cluster (多节点集群)
+-- scheduler (Cron 定时调度)
+-- auth / authz / ratelimit (认证 / 授权 / 限流)
+-- audit (审计日志)
+-- cost (成本计算)
+-- slo (SLO 评估)
+-- config (配置加载)
每个 VM 挂载两个磁盘:
- Drive 0 (rootfs): 只读,按运行时共享(
base.ext4/python.ext4/node.ext4等) - Drive 1 (code): 只读,16MB ext4,每个 VM 独立,包含用户函数代码
代码注入通过 debugfs 完成,不需要 root 权限或 mount 操作。
Firecracker VM
+-- /dev/vda (rootfs, 只读, 按运行时共享)
+-- /dev/vdb (代码磁盘, 只读, 每 VM 独立, 16MB)
| /code/handler (用户代码)
+-- /tmp (tmpfs, 64MB, 读写)
+-- Agent (PID 1, vsock:9999)
在 macOS 上使用 Apple Virtualization.framework 运行原生 Linux VM,通过 Go 工具 nova-vz(基于 Code-Hex/vz 绑定)管理 VM 生命周期。
Host (macOS) Guest (Linux VM)
┌───────────────────────────┐ ┌──────────────────────────┐
│ applevz.Manager │ │ Agent (PID 1) │
│ │ │ │
│ nova-vz 进程 │ vsock 代理 │ AF_VSOCK port 9999 │
│ (Code-Hex/vz) │────────────►│ │
│ UNIX socket │ VirtioFS │ 代码挂载: /code │
│ /tmp/nova-vz-*.sock │────────────►│ (virtiofs, 读写) │
│ │ │ │
│ 控制 socket │ │ Rootfs: ext4 镜像 │
│ save/restore/stop │ │ (Alpine linux-virt) │
└───────────────────────────┘ └──────────────────────────┘
与 Firecracker 的关键差异:
| 维度 | Firecracker | Apple VZ |
|---|---|---|
| 平台 | Linux x86_64/arm64 + KVM | macOS 13+ (arm64/x86_64) |
| 代码共享 | ext4 代码磁盘 (debugfs 注入) | VirtioFS (共享宿主机目录) |
| 通信 | vsock (AF_VSOCK 直连) | vsock (UNIX socket 代理) |
| 内核 | vmlinux (x86_64 uncompressed) | Image (arm64 uncompressed) |
| 快照 | 内存 + 状态快照 | macOS 14+ save/restore |
| 网络 | TAP + 网桥 + NAT | VirtioNet (可选) |
| 管理工具 | firecracker 二进制 | nova-vz (CGO, 需 codesign) |
Apple VZ 特有要求:
- 内核:Alpine linux-virt(需 VIRTIO_PCI 支持),解压为 Image 格式
- Initramfs:需包含 vsock 内核模块(
vsock,vmw_vsock_virtio_transport) - 构建:
nova-vz需要CGO_ENABLED=1,构建后需 codesign(com.apple.security.virtualizationentitlement) - Agent 自动检测 VirtioFS 挂载,回退到
/dev/vdb块设备
| 运行时 | Rootfs | 执行命令 |
|---|---|---|
| Go / Rust / Zig | base.ext4 | /code/handler input.json |
| Python | python.ext4 | python3 /code/handler input.json |
| Node.js | node.ext4 | node /code/handler input.json |
| Ruby | ruby.ext4 | ruby /code/handler input.json |
| Java | java.ext4 | java -jar /code/handler input.json |
| PHP | php.ext4 | php /code/handler input.json |
| Deno | deno.ext4 | deno run --allow-read /code/handler input.json |
| Bun | bun.ext4 | bun run /code/handler input.json |
| WASM | wasm.ext4 | wasmtime /code/handler -- input.json |
宿主机和 VM 之间通过 vsock 通信,使用长度前缀 + JSON 的二进制协议:
[4 bytes: 消息长度 BigEndian] [JSON payload]
| Type | 值 | 方向 | 用途 |
|---|---|---|---|
| Init | 1 | Host → VM | 初始化函数(运行时、handler、环境变量) |
| Exec | 2 | Host → VM | 执行函数(request_id、input、timeout) |
| Resp | 3 | VM → Host | 返回结果(output、error、duration_ms) |
| Ping | 4 | Host → VM | 健康检查 |
| Stop | 5 | Host → VM | 优雅停机 |
| Reload | 6 | Host → VM | 热更新代码 |
宿主机
┌──────────────────────────────────────────────┐
│ novabr0 (172.30.0.1/24) │
│ │ │
│ ├─ nova-abc123 (TAP) ← VM1 (172.30.0.2) │
│ ├─ nova-def456 (TAP) ← VM2 (172.30.0.3) │
│ └─ nova-ghi789 (TAP) ← VM3 (172.30.0.4) │
│ │
│ iptables NAT (MASQUERADE) → Internet │
└──────────────────────────────────────────────┘
- 自动创建网桥和 TAP 设备,自动分配 VM IP
- NAT 出站流量(VM 可访问外网)
- IP 通过内核参数自动配置,网关 172.30.0.1
| 领域 | 技术 | 选型理由 |
|---|---|---|
| 语言 | Go 1.22+ | 静态编译、并发原语成熟、交叉编译方便 |
| VM 隔离 | Firecracker | 亚秒级启动、极低内存开销、KVM 级隔离 |
| macOS 虚拟化 | Apple Virtualization.framework | 原生 hypervisor、VirtioFS/vsock、macOS 开发首选 |
| 容器后端 | Docker | 无 KVM 环境的降级方案,开发调试用 |
| 数据库 | PostgreSQL | JSONB 灵活存储函数配置,成熟稳定 |
| 数据库驱动 | pgx/v5 | 纯 Go 实现,连接池内建 |
| CLI | Cobra | Go 生态标准 CLI 框架 |
| VM 通信 | vsock (AF_VSOCK) | 无需网络栈、低延迟,Firecracker 原生支持 |
| 追踪 | OpenTelemetry | 厂商中立,支持 W3C Trace Context |
| 指标 | Prometheus client_golang | 云原生监控事实标准 |
| HTTP 路由 | Go 1.22 http.ServeMux |
原生支持路径参数,无需第三方路由库 |
| 代码注入 | debugfs (e2fsprogs) | 无需 mount 即可向 ext4 镜像写入文件 |
完整模式(Firecracker):
- Linux x86_64,内核支持 KVM(
/dev/kvm) - Firecracker 二进制、Linux 内核镜像(vmlinux)
- e2fsprogs(
mkfs.ext4、debugfs) - PostgreSQL 14+
- 运行时 rootfs 镜像
Apple VZ 模式(macOS 原生虚拟化):
- macOS 13+(Ventura 或更高,快照需 macOS 14+)
- Apple Silicon 或 Intel Mac
- PostgreSQL 14+(Docker 运行)
- arm64 Linux 内核 + initramfs(vsock 模块)+ 运行时 rootfs 镜像
Docker 模式(无需 KVM,适合本地开发):
- Docker Engine + PostgreSQL 14+
# Docker 模式(全部服务运行在容器内)
make dev # docker compose up --build(Postgres + 全部服务 + Lumen)
make seed # 注入示例函数
# macOS 原生模式(服务直接运行在宿主机,支持 Apple VZ 后端)
make dev-native # 构建 + 启动全部服务(Postgres 仍用 Docker)
make dev-native-status # 查看服务状态
make dev-native-stop # 停止全部服务服务端口:Zenith API :9000、Nova 控制平面 :9001、Comet gRPC :9090、Lumen Dashboard :3000、PostgreSQL :5432
原生模式下所有后端检测在宿主机上执行,Apple VZ、Docker、libkrun 等均可正确检测和使用。
# 1. 构建 linux 二进制
make build-linux
# 2. 一键部署(安装依赖、初始化 DB、配置 systemd 并启动服务)
sudo bash scripts/setup.sh安装完成后目录结构:
/opt/nova/
├── bin/nova, comet, corona, nebula, aurora, zenith, nova-agent
├── kernel/vmlinux
├── rootfs/
│ ├── base.ext4 # Go/Rust/Zig
│ ├── python.ext4 # Python
│ ├── node.ext4 # Node.js
│ └── ... # ruby/java/php/deno/bun/wasm
└── snapshots/
macOS 原生模式额外资产:
bin/nova-vz # Apple VZ 管理工具 (CGO + codesign)
assets/kernel/Image-alpine-arm64 # Alpine linux-virt 内核 (arm64 uncompressed)
assets/kernel/initramfs-alpine-arm64-vsock # Initramfs (含 vsock 内核模块)
assets/rootfs/*-arm64.ext4 # arm64 运行时 rootfs 镜像
# 注册函数
nova register hello-python \
--runtime python \
--handler main.handler \
--code /path/to/hello.py \
--memory 128 \
--timeout 30
# 调用函数
nova invoke hello-python --payload '{"name": "World"}'
# 其他命令
nova list
nova get hello-python
nova delete hello-python
nova daemon --idle-ttl 60s运行 make 或 make help 查看所有可用命令(安装了 fzf 时会启动交互式选择器)。
make build # 构建所有服务 (本机) + agent (linux/amd64)
make build-linux # 交叉编译所有服务 + agent 全部为 linux/amd64
make agent # 仅构建 guest agent
make nova-vz # 构建 nova-vz VM 管理工具 (macOS only, CGO + codesign)make frontend # npm install + npm run build
make frontend-dev # 启动开发服务器 (localhost:3000)make docker-backend # 构建 Nova 后端镜像
make docker-frontend # 构建 Lumen 前端镜像
make docker-runtimes # 构建全部运行时镜像
make docker-runtime-python # 构建单个运行时镜像make rootfs # Docker 内构建全部 rootfs 镜像 (x86_64)
make rootfs-arm64 # 构建 arm64 rootfs 镜像 (Apple VZ 用)
make rootfs-all # 构建全部架构 rootfs 镜像
make download-assets # 下载 Firecracker 二进制、内核等大文件make orbit # 构建 Orbit CLI(debug)
make orbit-release # 构建 Orbit CLI(release)
make orbit-clean # 清理 Orbit 构建产物make atlas # 构建 Atlas MCP Server
make atlas-linux # 交叉编译 Atlas for linux/amd64
make atlas-clean # 清理 Atlas 构建产物make all # 后端 + 前端 + Orbit + Atlas + 全部 Docker 镜像
make clean # 清理 bin/
make clean-all # 清理 bin/ + assets/ + lumen/orbit/atlas 构建产物make deploy SERVER=root@your-server # 交叉编译 + SCP 传输产物在 bin/ 目录。所有 Go 构建使用 CGO_ENABLED=0 确保静态链接。Agent 始终交叉编译为 linux/amd64。
函数代码遵循统一约定:handler(event, context) 签名,与 AWS Lambda 兼容。context 是类实例(Python/Ruby)或对象(Node/Deno/Bun),包含 function_name、request_id、memory_limit_in_mb、get_remaining_time_in_millis() 等字段。
def handler(event, context):
name = event.get("name", "Anonymous")
return {
"message": f"Hello, {name}!",
"runtime": "python",
"request_id": context.request_id,
}package main
import (
"encoding/json"
"fmt"
"os"
)
type Event struct {
Name string `json:"name"`
}
func main() {
data, _ := os.ReadFile(os.Args[1])
var event Event
json.Unmarshal(data, &event)
if event.Name == "" {
event.Name = "Anonymous"
}
result, _ := json.Marshal(map[string]string{
"message": fmt.Sprintf("Hello, %s!", event.Name),
"runtime": "go",
})
fmt.Println(string(result))
}function handler(event, context) {
const name = event.name || "Anonymous";
return {
message: `Hello, ${name}!`,
runtime: "node",
requestId: context.requestId,
};
}
module.exports = { handler };编译:CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o handler hello.go
use serde::{Deserialize, Serialize};
use std::{env, fs};
#[derive(Deserialize)]
struct Event { name: Option<String> }
#[derive(Serialize)]
struct Response { message: String, runtime: String }
fn main() {
let args: Vec<String> = env::args().collect();
let data = fs::read_to_string(&args[1]).unwrap();
let event: Event = serde_json::from_str(&data).unwrap();
let name = event.name.unwrap_or("Anonymous".into());
let resp = Response {
message: format!("Hello, {}!", name),
runtime: "rust".into(),
};
println!("{}", serde_json::to_string(&resp).unwrap());
}编译:cargo build --release --target x86_64-unknown-linux-musl
- 解释型语言(Python/Node/Ruby/PHP/Deno/Bun):只需定义
handler(event, context)函数,bootstrap 自动包装- 编译型语言(Go/Rust):读取
argv[1]文件,输出 JSON 到 stdout,须编译为静态链接的 Linux amd64 二进制
所有接口默认监听 :9000(通过 Zenith 网关)。
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /auth/register |
注册新用户 |
| POST | /auth/login |
登录获取 JWT |
| POST | /auth/logout |
登出 |
| POST | /auth/change-password |
修改密码 |
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /functions |
创建函数 |
| GET | /functions |
列出所有函数 |
| GET | /functions/{name} |
获取函数详情 |
| PATCH | /functions/{name} |
更新函数 |
| DELETE | /functions/{name} |
删除函数 |
| GET | /functions/{name}/code |
获取函数代码 |
| PUT | /functions/{name}/code |
更新函数代码 |
| GET | /functions/{name}/files |
列出函数文件 |
| GET | /functions/{name}/files/content |
获取文件内容 |
| GET | /functions/{name}/versions |
列出函数版本 |
| GET | /functions/{name}/versions/{version} |
获取指定版本 |
| POST | /functions/{name}/versions/{version}/activate |
激活版本 |
| GET | /functions/{name}/versions/{v1}/diff/{v2} |
版本差异对比 |
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /runtimes |
列出可用运行时 |
| POST | /runtimes |
创建自定义运行时 |
| POST | /runtimes/upload |
上传运行时镜像 |
| DELETE | /runtimes/{id} |
删除运行时 |
| GET | /backends |
列出后端及状态 |
| GET | /snapshots |
列出快照 |
| POST | /functions/{name}/snapshot |
创建快照 |
| DELETE | /functions/{name}/snapshot |
删除快照 |
| GET | /config |
获取系统配置 |
| PUT | /config |
更新系统配置 |
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /topics |
创建 Topic |
| GET | /topics |
列出 Topics |
| GET | /topics/{name} |
获取 Topic 详情 |
| DELETE | /topics/{name} |
删除 Topic |
| POST | /topics/{name}/publish |
发布事件 |
| POST | /topics/{name}/outbox |
创建 Outbox 条目 |
| GET | /topics/{name}/outbox |
列出 Outbox |
| POST | /topics/{name}/subscriptions |
创建订阅 |
| GET | /topics/{name}/subscriptions |
列出订阅 |
| GET | /subscriptions/{id} |
获取订阅详情 |
| PATCH | /subscriptions/{id} |
更新订阅 |
| DELETE | /subscriptions/{id} |
删除订阅 |
| GET | /subscriptions/{id}/deliveries |
列出投递记录 |
| POST | /subscriptions/{id}/replay |
重放订阅 |
| POST | /subscriptions/{id}/seek |
定位消费位点 |
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /workflows |
创建 DAG 工作流 |
| GET | /workflows |
列出工作流 |
| GET | /workflows/{name} |
获取工作流详情 |
| DELETE | /workflows/{name} |
删除工作流 |
| POST | /workflows/{name}/versions |
发布工作流版本 |
| GET | /workflows/{name}/versions |
列出工作流版本 |
| POST | /workflows/{name}/runs |
触发工作流运行 |
| GET | /workflows/{name}/runs |
列出运行记录 |
| GET | /workflows/{name}/runs/{runID} |
获取运行详情 |
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /triggers |
创建触发器 |
| GET | /triggers |
列出触发器 |
| GET | /triggers/{id} |
获取触发器 |
| PATCH | /triggers/{id} |
更新触发器 |
| DELETE | /triggers/{id} |
删除触发器 |
| POST | /functions/{name}/schedules |
创建调度规则 |
| GET | /functions/{name}/schedules |
列出调度规则 |
| DELETE | /functions/{name}/schedules/{id} |
删除调度规则 |
| PATCH | /functions/{name}/schedules/{id} |
切换启用/禁用 |
| POST | /gateway/routes |
创建网关路由 |
| GET | /gateway/routes |
列出网关路由 |
| PATCH | /gateway/routes/{id} |
更新路由 |
| DELETE | /gateway/routes/{id} |
删除路由 |
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /secrets |
创建 Secret |
| GET | /secrets |
列出 Secrets |
| DELETE | /secrets/{name} |
删除 Secret |
| POST | /apikeys |
创建 API Key |
| GET | /apikeys |
列出 API Keys |
| DELETE | /apikeys/{name} |
删除 API Key |
| GET | /tenants |
列出租户 |
| POST | /tenants |
创建租户 |
| PATCH | /tenants/{tenantID} |
更新租户 |
| DELETE | /tenants/{tenantID} |
删除租户 |
| POST | /rbac/roles |
创建角色 |
| GET | /rbac/roles |
列出角色 |
| POST | /rbac/permissions |
创建权限 |
| GET | /rbac/my-permissions |
获取当前用户权限 |
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /layers |
创建 Layer |
| GET | /layers |
列出 Layers |
| DELETE | /layers/{name} |
删除 Layer |
| PUT | /functions/{name}/layers |
设置函数 Layers |
| POST | /volumes |
创建 Volume |
| GET | /volumes |
列出 Volumes |
| DELETE | /volumes/{name} |
删除 Volume |
| POST | /cluster/nodes |
注册集群节点 |
| GET | /cluster/nodes |
列出集群节点 |
| POST | /ai/generate |
AI 生成代码 |
| POST | /ai/review |
AI 审查代码 |
| POST | /ai/rewrite |
AI 重写代码 |
| GET | /audit-logs |
列出审计日志 |
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /db-resources |
创建数据库资源 |
| GET | /db-resources |
列出数据库资源 |
| POST | /db-resources/{name}/bindings |
绑定函数到数据库 |
| PUT | /functions/{name}/slo |
设置 SLO 策略 |
| GET | /functions/{name}/slo |
获取 SLO 策略 |
| DELETE | /functions/{name}/slo |
删除 SLO 策略 |
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /functions/{name}/invoke |
同步调用函数 |
| POST | /functions/{name}/invoke-stream |
流式调用函数 (SSE) |
| POST | /functions/{name}/invoke-async |
异步调用函数 |
| POST | /functions/{name}/prewarm |
预热函数 VM |
| GET/PUT/DELETE | /functions/{name}/state |
函数级持久状态 |
| GET | /functions/{name}/logs |
函数调用日志 |
| GET | /functions/{name}/logs/stream |
日志实时流 (SSE) |
| GET | /functions/{name}/metrics |
函数维度指标 |
| GET | /functions/{name}/diagnostics |
函数诊断信息 |
| POST | /functions/{name}/diagnostics/analyze |
AI 诊断分析 |
| GET | /functions/{name}/slo/status |
SLO 达成状态 |
| GET | /functions/{name}/heatmap |
函数调用热力图 |
| GET | /functions/{name}/cost |
函数成本 |
| GET | /invocations |
全局调用日志 |
| GET | /async-invocations |
异步调用列表 |
| GET | /async-invocations/dlq |
死信队列 |
| POST | /async-invocations/dlq/retry-all |
重试全部死信 |
| GET | /stats |
池统计 |
| GET | /metrics |
JSON 格式全局指标 |
| GET | /metrics/prometheus |
Prometheus 格式指标 |
| GET | /metrics/timeseries |
全局时序数据 |
| GET | /metrics/heatmap |
全局调用热力图 |
| GET | /cost/summary |
全局成本摘要 |
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /health |
详细状态(Postgres + 池统计) |
| GET | /health/live |
Liveness(始终 200) |
| GET | /health/ready |
Readiness(Postgres 连通性) |
| GET | /health/startup |
Startup(Postgres 可达) |
配置加载优先级:CLI 标志 > 环境变量(NOVA_* 前缀)> 配置文件(YAML/JSON)
环境变量: NOVA_PG_DSN、NOVA_HTTP_ADDR、NOVA_LOG_LEVEL、NOVA_IDLE_TTL 等。
最小 JSON 配置:
{
"postgres": { "dsn": "postgres://nova:nova@localhost:5432/nova?sslmode=disable" },
"daemon": { "http_addr": ":9001", "log_level": "info" },
"pool": { "idle_ttl": "60s" }
}完整配置示例(YAML)
firecracker:
backend: firecracker # firecracker 或 docker
firecracker_bin: /opt/nova/bin/firecracker
kernel_path: /opt/nova/kernel/vmlinux
rootfs_dir: /opt/nova/rootfs
snapshot_dir: /opt/nova/snapshots
socket_dir: /tmp/nova/sockets
vsock_dir: /tmp/nova/vsock
log_dir: /tmp/nova/logs
bridge_name: novabr0
subnet: 172.30.0.0/24
boot_timeout: 10s
code_drive_size_mb: 16
vsock_port: 9999
max_vsock_message_mb: 8
docker:
code_dir: /tmp/nova/code
image_prefix: nova-runtime-
network: nova-net
port_range_min: 10000
port_range_max: 20000
cpu_limit: 1.0
postgres:
dsn: postgres://nova:nova@localhost:5432/nova?sslmode=disable
pool:
idle_ttl: 60s
cleanup_interval: 10s
health_check_interval: 30s
max_pre_warm_workers: 8
executor:
log_batch_size: 100
log_buffer_size: 1000
log_flush_interval: 500ms
log_timeout: 5s
daemon:
http_addr: ":9001"
log_level: info
tracing:
enabled: false
exporter: otlp
endpoint: localhost:4317
service_name: nova
sample_rate: 1.0
metrics:
enabled: true
namespace: nova
histogram_buckets: [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000]
logging:
level: info
format: text # text 或 json
include_trace_id: true
grpc:
enabled: false
addr: ":9090"
auth:
enabled: false
jwt:
algorithm: HS256
secret: ""
issuer: nova
api_keys:
enabled: false
rate_limit:
enabled: false
default_tier: standard
tiers:
standard:
requests_per_second: 100
burst_size: 200
premium:
requests_per_second: 1000
burst_size: 2000
secrets:
enabled: false
master_key: "" # 32 字节 hex 编码PostgreSQL,函数配置以 JSONB 存储。
完整表结构
-- 函数元数据
functions (
id UUID PRIMARY KEY,
name TEXT UNIQUE,
data JSONB
);
-- 函数版本(不可变)
function_versions (
function_id UUID,
version INT,
data JSONB,
created_at TIMESTAMPTZ,
PRIMARY KEY (function_id, version)
);
-- 函数别名
function_aliases (
function_id UUID,
name TEXT,
data JSONB,
created_at TIMESTAMPTZ,
updated_at TIMESTAMPTZ,
PRIMARY KEY (function_id, name)
);
-- 调用日志
invocation_logs (
id UUID PRIMARY KEY,
function_id UUID,
function_name TEXT,
runtime TEXT,
duration_ms BIGINT,
cold_start BOOLEAN,
success BOOLEAN,
error_message TEXT,
input_size BIGINT,
output_size BIGINT,
input JSONB,
output JSONB,
stdout TEXT,
stderr TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 运行时定义
runtimes (
id TEXT PRIMARY KEY,
name TEXT,
version TEXT,
status TEXT,
image_name TEXT,
entrypoint TEXT[],
file_extension TEXT,
env_vars JSONB
);
-- 键值配置
config (key TEXT PRIMARY KEY, value TEXT);
-- API 密钥
api_keys (
name TEXT PRIMARY KEY,
key_hash TEXT UNIQUE,
tier TEXT,
enabled BOOLEAN,
expires_at TIMESTAMPTZ,
created_at TIMESTAMPTZ
);
-- 加密密钥
secrets (
name TEXT PRIMARY KEY,
value TEXT, -- AES-GCM 加密
created_at TIMESTAMPTZ,
updated_at TIMESTAMPTZ
);
-- 限流桶
rate_limit_buckets (
key TEXT PRIMARY KEY,
tokens DOUBLE PRECISION,
last_refill TIMESTAMPTZ
);
-- 函数代码
function_code (
function_id UUID PRIMARY KEY,
source_code TEXT,
compiled_binary BYTEA,
source_hash TEXT,
binary_hash TEXT,
compile_status TEXT, -- pending/compiling/success/failed/not_required
compile_error TEXT,
created_at TIMESTAMPTZ,
updated_at TIMESTAMPTZ
);
-- 多文件支持
function_files (
id UUID PRIMARY KEY,
function_id UUID,
file_path TEXT,
content BYTEA,
size BIGINT,
created_at TIMESTAMPTZ
);Agent 作为 PID 1 在 VM 内运行,负责接收宿主机指令并执行用户代码。
- Process 模式:将输入写入
/tmp/input.json→ 执行<runtime> /code/handler /tmp/input.json→ 捕获 stdout → 解析 JSON - Persistent 模式:启动长驻进程 → 通过 stdin/stdout JSON 交互 → 崩溃时自动重启
注入的环境变量:NOVA_REQUEST_ID、NOVA_FUNCTION_NAME、NOVA_FUNCTION_VERSION、NOVA_MEMORY_LIMIT_MB、NOVA_TIMEOUT_S、NOVA_RUNTIME、NOVA_CODE_DIR、NOVA_MODE,以及运行时特定变量(PYTHONPATH、NODE_PATH 等)。
调用编排器,串联函数查找、代码加载、VM 获取、执行、指标记录的完整流程。异步日志批处理器(100 条/批、500ms 刷盘间隔)。
按函数维度管理 VM 池。后台任务:
- 每 10s 清理超过 IdleTTL 的空闲 VM + 代码 hash 过期的 VM
- 每 30s 对空闲 VM 发送 Ping 健康检查,移除无响应实例
- Daemon 启动后周期性预热 MinReplicas 数量的 VM
VM 全生命周期管理(默认后端):分配 CID + IP → 创建 TAP 设备 → debugfs 构建代码磁盘 → 启动 Firecracker → 等待就绪。
Firecracker 的降级替代方案,无需 KVM,适合 macOS 开发调试。通过 TCP 与 Agent 通信,代码目录挂载到容器 /code。
macOS 原生虚拟化后端,使用 Apple Virtualization.framework 运行 Linux VM。通过 nova-vz(Go + Code-Hex/vz)管理 VM 生命周期,VirtioFS 共享代码目录,vsock 通信(UNIX socket 代理)。支持快照 save/restore(macOS 14+)。
DAG 工作流引擎,支持多步骤函数编排、条件分支、并行执行。工作流以 YAML/JSON 定义,支持版本管理。
事件总线,实现 Topic → Subscription → Delivery 模型。支持 Outbox 模式(事务性发布)、消费位点管理、投递重试。
异步调用队列,支持自适应并发控制、DLQ(死信队列)、幂等去重。
外部事件源触发器:Kafka、RabbitMQ、Redis Stream、Webhook、Filesystem。统一触发器生命周期管理。
API 网关,支持自定义路由规则、参数映射(header/query/path → event)、路由级限流模板。
Layer 支持跨函数共享依赖包;Volume 提供持久化存储挂载。
集成大语言模型的代码助手,提供生成、审查、重写、诊断分析、测试生成、文档生成等能力。支持自定义 Prompt 模板。
多节点集群支持:节点注册/心跳、健康发现、请求路由、放置调度。
SLO 策略评估(延迟/成功率阈值)+ 函数级成本计算。
JWT + API Key 双认证模式。RBAC 权限模型(角色 → 权限绑定)。租户级菜单/按钮权限控制。
PostgreSQL 存储层:函数 CRUD、版本管理、别名、调用日志、运行时、配置、API Key、Secret、限流、代码存储、多文件支持。
全局指标(调用数、冷/暖启动、延迟、VM 生命周期)+ 按函数维度指标。Prometheus 导出 + 24 小时时序聚合。
函数元数据保存 CodeHash(SHA256)。每次调用时重新计算,若不一致则驱逐所有 VM 并使快照失效。
代码更新时向已有 VM 发送 Reload 消息:Agent 将 /code 重新挂载为读写 → 清空并写入新文件 → 重启 persistent 进程 → 重新挂载只读。
编译型语言的代码提交后由独立 goroutine 异步编译。编译状态:pending → compiling → success/failed。调用时若编译未完成则阻塞等待。
同一函数的并发冷启动请求通过 singleflight.Group 去重,防止雷群效应。
环境变量中的 $SECRET:name 引用在调用时由 Secrets Resolver 解析,密钥以 AES-GCM 加密存储,通过 Master Key 解密注入。
traceparent / tracestate 通过 Exec 消息传入 VM,Agent 注入为 NOVA_TRACE_PARENT 环境变量,实现跨 VM 边界的追踪链路关联。
Nova 是一个面向学习和内部使用的轻量 Serverless 平台。以下是与 AWS Lambda、Cloudflare Workers、Google Cloud Functions 的能力对比。
| 能力 | Nova | AWS Lambda | CF Workers | GCP Cloud Functions |
|---|---|---|---|---|
| VM 级隔离 | Firecracker KVM / Apple VZ | Firecracker KVM | V8 Isolate | gVisor |
| 多运行时 | 20+ 语言 | 7 语言 + 自定义 | JS/TS/WASM | 7 语言 |
| 冷启动优化 | 快照恢复 + 模板缓存 | SnapStart (Java) | 无冷启动 (V8) | Min instances |
| 可观测性 | OTEL + Prometheus + 结构化日志 | CloudWatch + X-Ray | Tail Workers + Logpush | Cloud Logging + Trace |
| 版本管理 | 不可变版本 + 别名 + 流量分割 | 版本 + 别名 + 加权路由 | Gradual Rollouts | Traffic splitting |
| 认证 | JWT + API Key + RBAC + 速率限制 | IAM + 资源策略 | API tokens | IAM + Invoker 角色 |
| 调度 | Cron 定时触发 | EventBridge 规则 | Cron Triggers | Cloud Scheduler |
| 热更新 | 解释型语言原地 Reload | 需重新部署 | 即时生效 | 需重新部署 |
| 事件源 | HTTP + Cron + Kafka + RabbitMQ + Redis + Webhook | 30+ 事件源 | HTTP + Queue + CRON + Email | 10+ 事件源 |
| 异步调用 | 异步队列 + DLQ + 自动重试 | DLQ + 重试 + 目的地路由 | Tail Workers | DLQ + 重试 |
| 流式响应 | SSE 流式调用 | Response Streaming | 原生 ReadableStream | — |
| 事件总线 | Topic → Subscription + Outbox 模式 | EventBridge | — | Eventarc |
| 工作流 | DAG 工作流引擎 | Step Functions | Workflows (beta) | Cloud Workflows |
| 依赖层 | Layer 跨函数共享 | Lambda Layers | 内置 (npm) | — |
| 持久存储 | Volumes + 函数状态 + DB 资源绑定 | EFS + S3 + DynamoDB | KV + R2 + D1 + Durable Objects | GCS + Firestore |
| AI 助手 | 代码生成 / 审查 / 重写 / 诊断 / 测试 | CodeWhisperer | AI Gateway | Duet AI |
| API 网关 | 自定义路由 + 参数映射 + 限流 | API Gateway (REST/HTTP/WS) | 内置 (路由/域名) | API Gateway |
| 自动伸缩 | 手动 Min/Max | 自适应 + 预留并发 | 自动(无限制) | 自适应 + Min instances |
| 网络隔离 | 单子网 + NAT | VPC + 安全组 + PrivateLink | — | VPC Connector |
| 边缘部署 | — | Lambda@Edge | 全球 300+ 节点 | — |
| 容器镜像部署 | Docker 后端(降级方案) | 容器镜像函数 | — | Cloud Run 集成 |
粗体行 = Nova 已具备的能力,普通行 = Nova 缺失或薄弱的能力。Nova 已实现绝大多数核心 Serverless 能力。
- 极致轻量:六个静态编译 Go 二进制 + Postgres,零外部依赖(无 Kafka/Redis/etcd)
- 冷启动快:Firecracker 快照恢复 + 代码磁盘模板缓存 + singleflight 去重
- 运行时最广:20+ 语言支持,自定义运行时,handler-only 风格零样板代码
- 跨平台后端:Firecracker (Linux KVM) + Apple VZ (macOS) + Docker (降级),统一 Agent 协议
- 可观测性好:OpenTelemetry trace 穿透 VM 边界 + Prometheus 指标 + 结构化日志 + SLO 评估
- 热更新:解释型语言代码更新不销毁 VM,原地 Reload
- 事件驱动:内置事件总线 + 异步队列 + DAG 工作流引擎 + 多源触发器
- AI 增强:代码生成、审查、诊断分析、测试生成一体化
按优先级排序:
P1 — 规模化必需
| 能力 | 说明 | 参考 |
|---|---|---|
| 自动伸缩策略 | 基于请求速率/延迟自适应调整 VM 池大小 | Lambda Provisioned Concurrency |
| 边缘部署 | 多区域 + 就近路由 | Lambda@Edge, CF Workers |
P2 — 企业级特性
| 能力 | 说明 | 参考 |
|---|---|---|
| 网络隔离 | 安全组、多子网、出入站规则 | VPC, Security Groups |
| 容器镜像部署 | 支持用户直接提交容器镜像 | Lambda Container Image |
为什么用 Firecracker 而不是容器? 硬件级隔离(KVM),启动速度 <125ms,内存开销 <5MB。适合多租户场景。
为什么在 macOS 上用 Apple Virtualization.framework? macOS 不支持 KVM/Firecracker。Apple VZ 提供原生 hypervisor 级隔离,支持 VirtioFS(高效文件共享)和 vsock(低延迟通信),与 Firecracker 共享同一套 Agent 和通信协议,实现跨平台无缝切换。
为什么用 vsock 而不是网络? 用于宿主机↔VM 控制通道,延迟更低,配置简单。网络用于 VM 访问外部服务,两者互补。
为什么用双磁盘?
rootfs 只读共享避免了每次复制文件系统。代码盘 16MB 通过 debugfs 注入,不需要 root 权限。
为什么 agent 是 /init? Firecracker VM 不需要完整 OS。agent 直接作为 PID 1 运行,省去 init 开销。
MIT