Этот файл документирует эту архитектуру в том виде, в котором она действительно существует в коде, проверенном файл за файлом по состоянию на 23 августа 2026 г., включая диаграммы, рисунки и выдержки. Это основная страница кластера «Rust Engineering»: она дает обзор и ссылки на углубленный технический анализ (Axum, рабочее пространство Cargo, шлюз, PostgREST, pg_graphql и остальная часть файла), опубликованный или находящийся в процессе публикации. Полное сравнение продукта с конкурирующим BaaS см. в нашем сравнении Aurabase и Supabase.
Самое необходимое
- Single Workspace Cargo: 18 ящиков (11 бизнес-сервисов,
auraCLI, 5 общих библиотек, Rust SDK), скомпилированных вместе однимcargo build --workspace. - Бизнес-код весит примерно 274 000 строк Rust (измерено с помощью
find+wc -l, 23 августа 2026 г.), распределенных по этим 18 ящикам. - Шлюз (
aura-gateway) разделяет две плоскости — данных (SDK, порт 8080) и управления (Studio, порт 8090) — каждая со своим собственным стеком промежуточного программного обеспечения и аутентификацией. - Aurabase не переписывает PostgREST: настоящий восходящий двоичный файл (v12.2.8) запускается для каждого арендатора и управляется службами Rust — добавленная стоимость заключается в нем, а не вместо него.
- Единственное заметное отклонение от чистого Rust: среда выполнения Edge Functions по умолчанию (режим
deno) представляет собой выделенный сервис TypeScript, основанный на изолятах V8; второй путь, собственный и в Rust через Wasmtime, существует для режимаwasm.
Что отличает Aurabase от сервиса, собранного BaaS
Большинство Postgres BaaS с открытым исходным кодом предоставляют свои услуги на нескольких языках. Это не оценочное суждение — это архитектурный факт, который имеет конкретные последствия: столько же цепочек компиляции, соглашений об ошибках и логики аутентификации, которые необходимо поддерживать в синхронизации, сколько языков задействовано.
В Aurabase уровень продукта, который мы пишем и поддерживаем сами — шлюз, аутентификация, база данных, режим реального времени, хранилище, уведомления, искусственный интеллект, обеспечение, управление учетными записями — представляет собой единое рабочее пространство Cargo, один язык, единую цепочку сборки. Это выбор, который документирован в этом файле.
«Единое ядро» не означает, что все, что работает в производстве, — это Rust. Как и любой Postgres BaaS, Aurabase также опирается на строительные блоки с открытым исходным кодом, которые она не писала: сам PostgreSQL, PostgREST, NATS. Структурное различие гетерогенного стека не связано с этими общими строительными блоками — оно касается уровня продукта, который их оркестрирует. В следующих разделах подробно описано, где именно проходит эта граница, включая единственное реальное исключение, которое мы обнаружили при аудите кода (Edge Functions, раздел 09).
18 ящиков, одна цепочка компиляции
Корневой Cargo.toml объявляет рабочую область Cargo в преобразователе v2 с 18 членами: 11 бизнес-сервисов, aura-cliCLI, 5 общих библиотек и aurabase-rsSDK. Вот фактический список в том виде, в каком он представлен в репозитории.
Общие зависимости живут в [workspace.dependencies]: Axum 0.8 (с WebSockets, multipart, макросами), Tokio, Tower/Tower-HTTP, SQLx 0.8 (Postgres + MongoDB через mongodb для вторичного механизма NoSQL), async-nats 0.47, sqlparser 0.53 (проверка SQL NL2SQL), oauth2 5, jsonwebtoken 10 и две библиотеки производительности, которые можно найти почти в каждом сервисе: mimalloc в качестве глобального распределителя и moka/dashmap для кэша в памяти.
В профиле выпуска документирован предполагаемый выбор: panic = "unwind" вместо "abort". Комментарий к файлу говорит сам за себя — паника в обработчике Axum/Tokio изолируется средой выполнения (затронутый запрос возвращает 500) вместо остановки всего процесса и отключения конкурирующих запросов. Согласно этому же примечанию, прирост производительностиabort (приблизительно от 1 до 2% от RPS) не стоит потери изоляции. Это компромисс между надежностью и скоростью, задокументированный в коде, а не маркетинговое заявление.
Один cargo build --workspace компилирует все это. Один cargo test --workspace запускает весь набор тестов. Один cargo clippy --workspace --all-targets -- -D warnings анализирует весь продукт по одним и тем же правилам. Подробности этой структуры — наследование зависимостей, внутренний граф между библиотеками и сервисами, подводные камни, с которыми мы столкнулись при ее росте — тема отдельной статьи: Архитектура рабочей области Cargo, как структурировать мультисервисный бэкенд Rust.
Строки Rust по сервисам (найти сервисы -name '*.rs' | xargs wc -l, 23 августа 2026 г.):
контроль ауры
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 + общий OIDC на проект, сеансы, MFA. |
| аура-дб | API базы данных: управление/перезагрузка PostgREST для каждого клиента, адаптеры Postgres и MongoDB, CDC. |
| поставщик ауры | Жизненный цикл проекта: выделенные или общие кластеры CNPG, роли, PostgREST на каждого арендатора. |
| аура-реальное время | WebSocket и SSE, широковещательная передача CDC, межэкземплярное присутствие через NATS JetStream KV. |
| хранилище ауры | Объекты, совместимые с S3 (MinIO), политики RLS, переносимые из Postgres. |
| функции ауры | Пограничные функции: развертывание, задания, cron, собственная среда выполнения Wasmtime (см. раздел 09). |
| аура-уведомления | Электронная почта, push-уведомления, исходящие веб-перехватчики. |
| будет иметь | Шлюз NL2SQL, RAG и LLM (собственный OpenAI, Anthropic, Gemini + любая конечная точка, совместимая с OpenAI). |
| аура-мигратор | Механизм миграции: единый источник схемы хранения, воспроизводимый при каждой подготовке. |
| контроль ауры | План управления: учетные записи разработчиков, организации, выставление счетов, Studio API. |
Интерфейс командной строки aura (≈ 9800 строк) использует те же API, что и SDK — у него нет привилегированного пути. Полная ссылка на каждую службу находится в документации по архитектуре и справочнике CLI .
5 ящиков, которые позволяют избежать дрейфа между сервисами
В стеке полиглотов правило безопасности — формат ошибок, защита SSRF, ограничение скорости — должно быть переопределено для каждого языка, и почти всегда оно меняется с течением месяцев. Aurabase кодирует его один раз в библиотеке рабочей области, используемой всеми соответствующими службами.
| ядро ауры | 7 259 l. | Общие примитивы: ошибки, конверт ответа API, утверждения JWT, внутренняя проверка подлинности между службами, помощники NATS, ограничение скорости, HTTP-клиент с защитой SSRF, автоматический выключатель, разрешение арендаторов, измерение. |
|---|---|---|
| адаптеры aura-db | 24 725 l. | Функция для адаптации единой базы данных, реализаций Postgres и MongoDB, используемых aura-db. |
| аура-крипто | 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 являются предметом специальной статьи: двухплоскостной шлюз, разработка шлюза API плоскости данных/плоскости управления в Rust.
Почему Aurabase не переопределяет PostgREST в Rust
Самогенерируемый REST API, который использует SDK, не является собственным модулем Rust: это настоящий исходный двоичный файл PostgREST (postgrest/postgrest:v12.2.8), развернутый в двух репликах для каждого выделенного проекта (deploy/cnpg/tenant-postgrest.yaml), размещенный совместно с экземпляром 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: Native GraphQL API на Postgres с pg_graphql.
Роль RLS и аутентификатора, а не прикладного уровня
Мультитенантная изоляция не опирается на фильтр WHERE tenant_id = ?, добавленный ORM приложения: каждый запрос проходит через роль aura_authenticator, которая перед выполнением запроса выполняет транзакцию SET LOCAL ROLE tenant_<uuid> — именно ту модель, которую ожидает сам PostgREST. Безопасность на уровне строк делает все остальное на уровне ядра, а не на уровне бизнес-кода.
Не все проекты используют одну и ту же топологию Postgres. Код aura-provisioner предоставляет тип ProjectInstanceKind как минимум с двумя реальными вариантами: FullyDedicated (экземпляр CNPG, полностью посвященный проекту) и SharedClusterDedicated (схема, изолированная RLS в общем кластере CNPG). Подписываемый план определяет топологию — это не единое обещание «выделенной базы для всех».
Вопрос «почему выделенная база для каждого проекта, а не просто изоляция приложения» является темой отдельной статьи: RLS и выделенная база для каждого проекта. Документация по безопасности на уровне строк описывает практическую реализацию.
Ядро NATS, а не JetStream: асинхронный обмен сообщениями между службами
Десять из одиннадцати бизнес-сервисов объявляют async-nats прямой зависимостью в своем Cargo.toml — без этого обходится только aura-migrator. О чем не говорит это название ящика: эти сервисы почти везде используют NATScore pub/sub API (Client::publish / publish_with_headers, доставка не более одного раза без сохранения или воспроизведения), а не JetStream. Это случай, проверенный в коде для трех наиболее важных применений: распространение CDC PostgreSQL на aura-realtime, уведомление о заданиях Edge Functions в aura-functions (сам DLQ находится в Postgres, а не в NATS) и события подготовки между aura-provisioner и остальным парком.
JetStream — режим сохранения и именованных потоков NATS — появляется только в одном проверенном месте в монорепозитории: хранилище KV присутствия между экземплярами в aura-realtime (корзин aura_presence, хранилище памяти, 60-секундное max_age), которое синхронизирует, кто к какому каналу подключен, в нескольких экземплярах ws-front — общее состояние между экземплярами, а не поток событий для воспроизведения. Никакие постоянные потоки JetStream не были обнаружены где-либо еще в рабочей области. Детали конвейера CDC — wal2json, выбор уникального cdc-worker с помощью Lease Kubernetes, разветвление ядра NATS на реплики ws-front, повторная проверка RLS подписчиком — являются предметом специальной статьи: транслирует PostgreSQL CDC с NATS. Документация Realtime описывает использование на стороне SDK.
Edge Functions: две среды выполнения для двух нужд
Это самый важный нюанс этого файла и единственное реальное отклонение от чистого Rust в коде продукта Aurabase. Каждая функция содержит поле runtime, значение которого равно "wasm" или "deno". Обработчик вызова соответственно выбирает путь выполнения — собственно фрагмент, закомментированный в самом коде:
Режим wasm является встроенным: aura-functions напрямую зависит от Wasmtime (версия 43, функции async и cranelift) и выполняет модуль в том же процессе Rust, с подсчетом топлива, прерыванием по эпохам и ограничением памяти через StoreLimits. Режим deno — тот, который используется по умолчанию в редакторе Studio, для почти прямой совместимости Deno.serve() с существующим кодом Supabase — делегирует выполнение aura-edge-runtime, отдельной службе TypeScript длиной около 550 строк, явно смоделированной — сам комментарий заголовка исходного файла цитирует его — на supabase/edge-runtime (MIT лицензия), которая изолирует каждый вызов в отдельный изолят V8.
Управление — развертывание, разрешения, задания, cron, квоты — полностью остается в Rust в aura-functions. Только выполнение пользовательского кода в режиме deno завершает двоичный файл Rust. Это оправданный инженерный компромисс (изоляты V8 — это то, что Deno изначально обеспечивает для такого уровня изолированной программной среды), а не упущение, о котором мы предпочитаем молчать. Сравнение Wasmtime и Wasmer и анализ холодного запуска WebAssembly, которые скоро появятся в этом файле, дадут дальнейшее развитие этой темы.
Инструкции по обоим путям развертывания см. в разделе Edge Functions. Сценарий миграции Deno из Supabase см. в разделе Миграция проекта Supabase в Aurabase, где это различие уже задокументировано до этого файла.
Что конкретно меняет для вас это единое сердце
Если вы просто вызываете API через SDK, эта архитектура невидима — в этом и заключается цель. В основном это имеет значение для трех аудиторий: тех, кто оценивает эксплуатационную надежность мультитенантного бэкэнда перед переносом в него производственных данных, тех, кто планирует внести свой вклад в репозиторий (MIT, одиночный монорепозиторий) и тех, кто хочет понять, почему патч безопасности на стороне Aurabase распространяется быстро, а не медленно.
Конкретно: одна микросхема (cargo build --workspace, cargo test --workspace, cargo clippy --workspace --all-targets -- -D warnings) покрывает 90% или более поверхности продукта. Проверка кода aura-core потенциально затрагивает десять сервисов одновременно — в лучшую сторону (исправление не теряется в процессе) и в худшую (плохо изолированное изменение распространяется так же быстро). Это компромисс, а не волшебное решение — и именно поэтому мы документируем реальную архитектуру, а не маркетинговое резюме.
Остальная часть файла Rust Engineering
Эта основная страница ссылается на технический анализ кластера по мере его публикации. Актуальный статус на момент публикации этой страницы — ссылки становятся активными, как только соответствующая статья появляется в сети.
Кластер A — Структура и архитектура
Axum против Actix-web: какой фреймворк для серверной части Rust в производстве?Опубликовано
Архитектура рабочей области Cargo: как структурировать мультисервисный бэкенд на RustОпубликовано
Двухплоскостной шлюз: проектирование API-шлюза уровня данных/управления в RustОпубликовано
Кластер B — Самогенерируемый API на Postgres
PostgREST: что на самом деле охватывает совместимость и какие альтернативы существуютОпубликовано
Нативный GraphQL API на Postgres с pg_graphql: что Hasura и PostGraphile не делают одинаковоОпубликовано
RLS и выделенная база для каждого проекта: выбор многопользовательской изоляции от AurabaseОпубликовано
Кластер C — Реальное время и обмен сообщениями
Распространение PostgreSQL CDC с помощью NATS: архитектура реального времениОпубликовано
Кластер D — Edge-функции WebAssembly
| Wasmtime vs Wasmer: какая среда выполнения WebAssembly для пограничных функций находится в производстве | Вскоре |
|---|---|
| Edge-функции в Rust/WASM в сравнении с Cloudflare Workers и Vercel Edge | Вскоре |
| Холодный старт WebAssembly: что на самом деле говорят тесты (и чего мы пока не можем сказать) | Вскоре |
Кластер E — Миграция и альтернативы
Перенесите проект Supabase в Aurabase без переписывания политик RLSОпубликовано
Суверенный самостоятельный хостинг: позиционирование Aurabase против родного для Rust BaaSСкоро выйдет