该文件记录了该架构实际存在于代码中的情况,截至 2026 年 8 月 23 日逐个文件进行验证 - 包括图表、图形和摘录。这是“Rust Engineering”集群的支柱页面:它提供了概述,并链接到已发布或正在发布的深入技术分析(Axum、Cargo 工作区、网关、PostgREST、pg_graphql 和文件的其余部分)。有关与 BaaS 竞争产品的完整产品比较,请参阅我们的 比较 Aurabase 与 Supabase。
要点
- 单个工作区货物:由单个
cargo build --workspace编译在一起的 18 个箱子(11 个业务服务、auraCLI、5 个共享库、Rust SDK)。 - 业务代码大约有 274,000 行 Rust(通过
find+wc -l测量,2026 年 8 月 23 日),分布在这 18 个箱子中。 - 网关 (
aura-gateway) 分隔两个平面 - 数据(SDK,端口 8080)和管理(Studio,端口 8090) - 每个平面都有自己的中间件堆栈和身份验证。 - Aurabase 不会重写 PostgREST:真正的上游二进制文件 (v12.2.8) 按租户运行,由 Rust 服务编排 — 附加值围绕它,而不是相反。
- 与纯 Rust 唯一显着的区别:Edge Functions(
deno模式)的默认运行时是基于 V8 Isolates 的专用 TypeScript 服务;wasm模式存在第二条路径,即本机路径和 Rust 中的 Wasmtime 路径。
Aurabase 与 BaaS 组装服务的区别是什么
大多数开源 Postgres BaaS 以多种语言打包其服务。这不是一个价值判断——它是一个具有具体后果的架构事实:有多少种语言就需要多少编译链、错误约定和验证逻辑来保持同步。
在 Aurabase,我们自己编写和维护的产品层(网关、身份验证、数据库、实时、存储、通知、人工智能、配置、帐户管理)是单个 Cargo 工作区、单一语言、单一构建链。这是该文件记录的选择。
“统一核心”并不意味着生产中运行的所有内容都是 Rust。与任何 Postgres BaaS 一样,Aurabase 也依赖于并非由其编写的开源构建块:PostgreSQL 本身、PostgREST、NATS。异构堆栈的结构差异与这些共享构建块无关——它涉及编排它们的产品层。以下各节详细介绍了该边界到底经过的位置,包括我们在审核代码时发现的唯一真正的异常(边缘函数,第 09 节)。
18 个板条箱,1 个编译链
根 Cargo.toml 在解析器 v2 中声明了 Cargo 工作区 ,具有 18 个成员:11 个业务服务、aura-cliCLI、5 个共享库和 aurabase-rsSDK。这是存储库中显示的实际列表。
共享依赖项位于 [workspace.dependencies]中:Axum 0.8(带有 WebSockets、多部分、宏)、Tokio、Tower/Tower-HTTP、SQLx 0.8(Postgres + MongoDB 通过 mongodb 作为辅助 NoSQL 引擎)、async-nats 0.47、sqlparser 0.53(NL2SQL 的 SQL 验证)、oauth2 5、jsonwebtoken 10,以及几乎每个服务中都有的两个性能库:mimalloc 作为全局分配器,moka/dashmap 用于内存缓存。
发布配置文件记录了一个假定的选择: panic = "unwind" 而不是 "abort"。文件注释是不言自明的 - Axum/Tokio 处理程序中的恐慌由运行时隔离(受影响的请求返回 500),而不是关闭整个进程并切断竞争请求。根据同一篇注释,abort 的性能增益(大约 RPS 的 1 到 2%)不值得绝缘损失。这是代码中记录的可靠性与速度的权衡,而不是营销声明。
单个 cargo build --workspace 即可编译整个内容。单个 cargo test --workspace 运行整个测试套件。单个 cargo clippy --workspace --all-targets -- -D warnings 使用相同的规则对整个产品进行 lint 处理。这个结构的细节——依赖关系的继承、库和服务之间的内部图、我们在发展它时遇到的陷阱——是一篇专门文章的主题:Cargo 工作空间架构,如何构建多服务 Rust 后端。
按服务划分的 Rust 行(find services -name '*.rs' | xargs wc -l,2026 年 8 月 23 日):
光环控制
36 024
光环数据库
30 255
光环认证
28 431
光环供应者
28 271
光环通知
18 498
将会有
18 305
光环网关
16 938
光环实时
16 799
光环储存
13 747
光环功能
11 619
光环迁移者
538
不包括共享库(aura-db-adapters:24,725 行、aura-core:7,259、aura-migrations:3,641、aura-crypto:2,718、aura-telemetry:201)、CLI(aura-cli:9,845)和 Rust SDK(aurabase-rs:6,363)。 aura-migrator 是一个一次性迁移作业,而不是一个长期存在的 HTTP 服务器,它特意保留了工作区中最小的服务。
11 个业务服务,每个服务都有一个独立的 Axum 服务器
每个服务都是一个独立的 Axum/Tokio 二进制文件,具有自己的配置和端口。十一个暴露 /health 和 /metrics 中的十个并声明 mimalloc 作为全局分配器 - 唯一的例外, aura-migrator,是一个单一用途的作业而不是连续运行的服务器。
| 光环网关 | 双平面网关(数据:8080,管理:8090):代理所有其他服务。 |
|---|---|
| 光环认证 | 身份验证:JWT、15 个命名 OAuth 提供商 + 每个项目、会话、MFA 的通用 OIDC。 |
| 光环数据库 | 数据库 API:PostgREST 管理/每个租户重新加载、Postgres 和 MongoDB 适配器、CDC。 |
| 光环供应者 | 项目生命周期:每个租户专用或共享 CNPG 集群、角色、PostgREST。 |
| 光环实时 | WebSocket 和 SSE、CDC 广播,通过 NATS JetStream KV 跨实例存在。 |
| 光环储存 | S3 兼容对象 (MinIO)、可从 Postgres 传输的 RLS 策略。 |
| 光环功能 | 边缘功能:部署、作业、cron、本机 Wasmtime 运行时(请参阅第 09 节)。 |
| 光环通知 | 电子邮件、推送、传出 webhook。 |
| 将会有 | NL2SQL、RAG 和 LLM 网关(原生 OpenAI、Anthropic、Gemini + 任何 OpenAI 兼容端点)。 |
| 光环迁移者 | 迁移引擎:在每次配置时重放保存模式的单一来源。 |
| 光环控制 | 管理计划:开发者帐户、组织、计费、Studio API。 |
aura CLI(约 9,800 行)使用与 SDK 相同的 API — 它没有特权路径。每个服务的完整参考位于 架构文档 和 CLI 参考中。
避免服务间漂移的 5 个 crate
在多语言堆栈中,安全规则(错误格式、SSRF 保护、速率限制)必须以每种语言重新实现,并且几乎总是在几个月内发生变化。 Aurabase 在工作区库中对其进行一次编码,供所有相关服务使用。
| 光环核心 | 7 259 l. | 共享原语:错误、API 响应信封、JWT 声明、内部服务到服务身份验证、NATS 帮助程序、速率限制、SSRF 保护的 HTTP 客户端、断路器、租户解析、计量。 |
|---|---|---|
| aura-db 适配器 | 24 725 l. | Trait 用于适应 aura-db 使用的统一数据库、Postgres 和 MongoDB 实现。 |
| 光环加密 | 2 718 l. | 密码散列、令牌生成、JWT 签名/验证、字段级加密。 |
| 光环迁移 | 3 641 l. | 迁移引擎 - 租户模式的单一来源,由配置者重播(不是每个服务的迁移/特定文件夹)。 |
| 光环遥测 | 201 l. | OpenTelemetry + 跟踪配置,由 11 个服务共享。 |
直接后果: aura-core 中的安全补丁(例如 SSRF 保护)传播到下一个 cargo build中的每个消费者服务,而不是通过五种语言的五个单独补丁。
双计划:SDK 流量与 Studio 流量
aura-gateway 分隔两个既没有相同客户端也没有相同身份验证模型的表面。数据平面(端口 8080,变量 GATEWAY_PORT)接收 SDK/应用程序流量,并通过 API 密钥(apikey、 X-API-Key 或 ?apikey=)进行身份验证。管理平面(端口 8090, MANAGEMENT_PORT)接收 Studio/admin 流量,并由 JWT 控制台 (Authorization: Bearer) 进行身份验证。
每个平面都带有自己的中间件堆栈 - 查询识别,访问日志,速率限制,身份验证(特定于平面),断路器,然后代理 - 在单独的模块(middleware/rate_limit.rs, middleware/circuit_breaker.rs, middleware/auth_data_plane.rs, middleware/auth_management_plane.rs)中实现,而不是在不应以相同方式相互信任的两个表面之间意外共享的单个链。方式。
中间件的确切顺序、每个目标的速率限制以及 NATS/HTTP 代理是专门文章的主题:双平面网关,在 Rust中设计数据平面/管理平面 API 网关。
为什么 Aurabase 不在 Rust 中重新实现 PostgREST
SDK 使用的自行生成的 REST API 不是内部 Rust 模块:它是真正的上游二进制文件 PostgREST (postgrest/postgrest:v12.2.8),部署在每个专用项目 (deploy/cnpg/tenant-postgrest.yaml) 2 个副本中,与租户的 CNPG 实例位于同一位置。 aura-provisioner 创建此部署,aura-db 在每次模式重新加载后探测其端点 OPTIONS 以确认 PostgREST 已考虑 DDL 更改。
这是一个假定的架构选择,而不是捷径:PostgREST 是一个成熟的、广泛采用的项目,其行为在 Rust 中一点点重写不会带来任何结果。 Aurabase 的 Rust 工作重点是 — 多租户路由、配置、通过 NetworkPolicy 进行的网络隔离、与网关的共享身份验证、精心编排的模式重新加载 — 而不是查询引擎本身。这种兼容性真正涵盖的内容以及它停止的地方是另一篇文章的主题:PostgREST,实际兼容性和替代方案。
GraphQL 端的逻辑相同:Postgres 扩展 pg_graphql(预编译的 .deb 包,v1.6.1)安装在专用 CNPG 映像中,并通过 POST /v1/control/projects/{project_id}/graphql/enable 端点按需激活每个项目 — 也不是重写的 GraphQL 引擎。与 Hasura 和 PostGraphile 的详细信息和诚实比较: Postgres 上的 Native GraphQL API with pg_graphql。
RLS 和验证器角色,而不是应用层
多租户隔离不依赖于应用程序 ORM 添加的 WHERE tenant_id = ? 过滤器:每个请求都会经过 aura_authenticator角色,该角色在执行请求之前执行 SET LOCAL ROLE tenant_<uuid> 事务范围 — 这正是 PostgREST 本身所期望的模型。行级安全性在引擎级别而不是业务代码级别完成其余的工作。
并非所有项目都共享相同的 Postgres 拓扑。 aura-provisioner 代码公开了 ProjectInstanceKind 类型,该类型至少有两个实际变体:FullyDedicated(完全专用于该项目的 CNPG 实例)和 SharedClusterDedicated(在共享 CNPG 集群上由 RLS 隔离的架构)。订阅的计划决定了拓扑——它并不是“为每个人提供专用基地”的统一承诺。
“为什么每个项目都有专用基础而不是纯粹的应用程序隔离”的角度是一篇专门文章的主题: RLS 和每个项目专用基础。 行级安全性 文档涵盖了实际实现。
NATS 核心,而不是 JetStream:服务之间的异步消息传递
11 个业务服务中有 10 个将 async-nats 声明为其 Cargo.toml 中的直接依赖项 — 只有 aura-migrator 没有它。这个板条箱名称没有说明什么:这些服务几乎在所有地方都使用 NATS 的核心发布/订阅 API (Client::publish / publish_with_headers、 最多一次交付 ,无需持久性或重播),而不是 JetStream。这是在最重要的三个用途的代码中验证的情况:将 PostgreSQL CDC 分发到 aura-realtime、在 aura-functions 中边缘函数作业的通知(DLQ 本身位于 Postgres 中,而不是在 NATS 中),以及在 aura-provisioner 和队列的其余部分之间配置事件。
JetStream — NATS 的持久性和命名流模式 — 仅出现在单一存储库中的一个经过验证的位置:aura-realtime 中的跨实例存在 KV 存储(存储桶 aura_presence、内存存储、60 秒 max_age),它同步跨 ws-front 的多个实例连接到哪个通道的人员 — 一种跨实例共享状态,而不是要重播的事件流。在工作区的其他地方没有找到持久的 JetStream 流。 CDC 管道的详细信息 - wal2json、Lease Kubernetes 选择唯一的 cdc-worker、核心 NATS 扇出到 ws-front副本、订阅者的 RLS 重新验证 - 是一篇专门文章的主题:使用 NATS广播 PostgreSQL CDC。 实时文档 涵盖了 SDK 端的用法。
Edge Functions:两个运行时满足两种需求
这是该文件最重要的细微差别,也是 Aurabase 产品代码中与纯 Rust 的唯一真正区别。每个函数都带有一个 runtime 字段,其值是 "wasm" 或 "deno"。调用处理程序相应地选择执行路径 - 实际片段,在代码本身中注释掉:
wasm 模式是原生的: aura-functions 直接依赖于 Wasmtime (版本 43,具有 async 和 cranelift),并在同一个 Rust 进程中执行该模块,并通过 StoreLimits进行燃料计数、纪元中断和内存限制。 deno 模式 - Studio 编辑器中默认使用的模式,几乎直接 Deno.serve() 与现有 Supabase 代码兼容 - 将执行委托给 aura-edge-runtime,这是一个大约 550 行的单独 TypeScript 服务,显式建模 - 源文件头注释本身引用了它 - 在 supabase/edge-runtime (MIT许可证),它将每个调用隔离到其自己的 V8 隔离中。
控制——部署、权限、作业、cron、配额——完全保留在 Rust 的 aura-functions中。只有在 deno 模式下执行用户代码才会退出 Rust 二进制文件。这是一种可防御的工程妥协(V8 Isolates 是 Deno 本身为这种级别的沙箱提供的),而不是我们宁愿保持沉默的遗漏。本文件中即将推出的 Wasmtime 与 Wasmer 比较以及 WebAssembly 冷启动分析将进一步讨论这个主题。
有关两个部署路径的操作文档,请参阅 Edge Functions。有关 Supabase 的 Deno 迁移手册,请参阅 将 Supabase 项目迁移到 Aurabase,它已经在此文件之前记录了这种区别。
这颗统一的心具体为你带来了什么改变
如果你只是通过 SDK 调用 API,那么这个架构是不可见的——这就是目标。它主要对三个受众很重要:那些在将生产数据迁移到多租户后端之前评估多租户后端的操作可靠性的人,那些计划为存储库做出贡献的人(MIT,单一 monorepo),以及那些想要了解为什么 Aurabase 端的安全补丁传播得很快而不是缓慢的人。
具体来说:单个 IC(cargo build --workspace、cargo test --workspace、cargo clippy --workspace --all-targets -- -D warnings)覆盖产品表面的 90% 或更多。对 aura-core 进行代码审查可能会同时影响十个服务 - 好的是(修复不会在途中丢失),而坏的则是(隔离不佳的更改传播得同样快)。这是一种妥协,而不是一个神奇的解决方案——这正是我们记录实际架构而不是营销摘要的原因。
Rust 工程文件的其余部分
该支柱页面链接到已发布的集群技术分析。本页面发布时的实际状态 - 一旦相应的文章上线,链接就会变为活动状态。
集群 A — 框架和架构
Axum 与 Actix-web:哪个框架适合生产中的 Rust 后端?已发布
Cargo 工作区架构:如何构建多服务 Rust 后端已发布
双平面网关:用 Rust 设计数据平面/管理平面 API 网关已发布
集群 B — Postgres 上自行生成的 API
PostgREST:兼容性真正涵盖什么,以及存在哪些替代方案已发布
Postgres 上带有 pg_graphql 的本机 GraphQL API:Hasura 和 PostGraphile 不做相同的事情已发布
RLS 和每个项目的专用基座:选择 Aurabase 的多租户绝缘已发布
集群 C — 实时和消息传递
使用 NATS 分发 PostgreSQL CDC:实时架构已发布
集群 D — 边缘函数 WebAssembly
| Wasmtime 与 Wasmer:生产环境中 Edge Functions 的 WebAssembly 运行时 | 即将推出 |
|---|---|
| Rust/WASM 中的边缘函数与 Cloudflare Workers 和 Vercel Edge | 即将推出 |
| 冷启动 WebAssembly:基准测试真正说明了什么(以及我们还不能说的) | 即将推出 |
集群 E — 迁移和替代方案
将 Supabase 项目迁移到 Aurabase,无需重写 RLS 策略已发布
主权自托管:将 Aurabase 定位为 Rust 原生 BaaS 即将推出