WASI 0.3 и смерть холодных стартов: серверный Wasm в продакшене
Engineering Team
WASI 0.3 — и это меняет всё
WebAssembly System Interface (WASI) 0.3 вышел в феврале 2026 года, и он закрывает последний пробел, который не позволял серверному Wasm войти в мейнстрим производственных нагрузок. Благодаря нативному async I/O, первоклассным потоковым типам и полной поддержке TCP/UDP-сокетов, Wasm-модули теперь могут делать всё то же, что и контейнеры — при кратно меньших затратах на запуск.
Если вы отвергали Wasm на сервере как игрушку, этот релиз — повод пересмотреть позицию. AWS, Google Cloud и Azure запустили Wasm-бессерверные среды выполнения в 2025-2026 годах, а такие компании, как Fermyon, Fastly и Cloudflare, уже более двух лет запускают Wasm в продакшене.
Что поставляется в WASI 0.3
WASI 0.2 (январь 2024) представил Component Model и базовые интерфейсы ввода-вывода. WASI 0.3 дополняет этот фундамент тремя критическими нововведениями:
Нативный Async I/O
WASI 0.2 предлагал только блокирующий I/O. Если ваш Wasm-модуль должен был обрабатывать несколько одновременных подключений, вы были ограничены потоками или неудобными циклами поллинга. WASI 0.3 вводит нативную асинхронную модель, которая напрямую маппится на языковые async-примитивы:
- Rust:
async fnсtokioилиasync-stdкомпилируется в нативный WASI 0.3 async - Go: горутины маппятся на WASI-асинхронные задачи
- Python: цикл событий
asyncioинтегрируется с планировщиком WASI - JavaScript:
Promiseиasync/awaitработают из коробки через JCO
Среда выполнения (Wasmtime, WasmEdge или Spin) управляет циклом событий. Ваш код использует идиоматический async на любом выбранном языке, а уровень WASI берёт на себя остальное.
// Rust async HTTP-обработчик, скомпилированный в WASI 0.3
use wasi::http::types::{IncomingRequest, ResponseOutparam};
async fn handle_request(req: IncomingRequest, resp: ResponseOutparam) {
// Асинхронное чтение тела запроса
let body = req.consume().await.unwrap();
let bytes = body.read_all().await.unwrap();
// Исходящий HTTP-вызов (неблокирующий)
let api_response = wasi::http::outgoing_handler::handle(
build_api_request(&bytes)
).await.unwrap();
// Потоковая передача ответа
let out = resp.set(200, &headers);
out.body().write_all(&api_response.body()).await.unwrap();
}
Потоковые типы
WASI 0.3 вводит stream<T> и future<T> как первоклассные типы в системе типов Component Model. Это позволяет компонентам передавать потоковые данные через языковые границы без сериализации:
// Определение WIT-интерфейса с потоковыми типами
interface data-processor {
// Функция, принимающая поток байтов и возвращающая поток обработанных записей
process: func(input: stream<list<u8>>) -> stream<record>;
record record {
id: u64,
payload: list<u8>,
timestamp: u64,
}
}
Это позволяет создавать потоковые конвейеры, где Rust-парсер данных передаёт данные в Python ML-модель, а та — в Go-сериализатор — всё в рамках одного процесса, через zero-copy потоки.
Полная поддержка сокетов
WASI 0.3 предоставляет полные API для TCP- и UDP-сокетов, включая:
tcp::listenиtcp::connectдля серверных и клиентских сокетовudp::bindиudp::send_to/udp::recv_fromдля датаграммных протоколов- TLS-терминацию через
wasi:sockets/tls - DNS-резолвинг через
wasi:sockets/name-lookup
Это означает, что Wasm-модули теперь могут реализовывать пользовательские протоколы, драйверы баз данных, клиенты очередей сообщений и любые другие сетевые нагрузки без использования HTTP как транспортного уровня.
Component Model: полиглотная композиция
Component Model, стабилизированный в WASI 0.2 и доработанный в 0.3, делает серверный Wasm принципиально отличным от контейнеров. Он позволяет компоновать несколько Wasm-компонентов — написанных на разных языках — в одно приложение:
+------------------+ +-------------------+ +------------------+
| Auth Component |---->| Business Logic |---->| Data Layer |
| (Rust) | | (Python) | | (Go) |
+------------------+ +-------------------+ +------------------+
| | |
wasi:http wasi:keyvalue wasi:sql
capability capability capability
Каждый компонент:
- Работает в собственной песочнице с безопасностью на основе возможностей (без ambient authority)
- Объявляет, какие системные интерфейсы ему нужны, через WIT
- Взаимодействует с другими компонентами через типизированные интерфейсы, а не через сериализованный JSON
- Может обновляться независимо без повторного развёртывания всего приложения
Это не теоретическое будущее. Fermyon Spin 3.0, выпущенный в январе 2026 года, поддерживает мультикомпонентные приложения в продакшене. Fastly Compute предлагает композицию компонентов с конца 2025 года.
Производительность: микросекундные холодные старты против секунд контейнеров
Главная метрика, делающая Wasm привлекательным для бессерверных сред — это время холодного старта. Вот как выглядят числа в реальных бенчмарках:
| Метрика | Docker-контейнер | AWS Lambda | Wasm-модуль (Spin) | Wasm-модуль (Wasmtime) |
|---|---|---|---|---|
| Холодный старт | 500мс - 5с | 100мс - 2с | 0.5мс - 3мс | 0.3мс - 2мс |
| Тёплый вызов | 1мс - 50мс | 1мс - 20мс | 0.1мс - 1мс | 0.05мс - 0.5мс |
| Потребление памяти | 50МБ - 500МБ | 128МБ - 10ГБ | 1МБ - 20МБ | 1МБ - 15МБ |
| Размер бинарника | 50МБ - 2ГБ | N/A (zip-пакет) | 1МБ - 30МБ | 1МБ - 30МБ |
| Затраты на запуск | ОС + рантайм + приложение | Рантайм + приложение | Инстанциация модуля | Инстанциация модуля |
| Изоляция | Linux namespaces + cgroups | Firecracker microVM | Wasm-песочница | Wasm-песочница |
Разница не инкрементальная — это три порядка величины. Холодный старт Wasm, измеряемый в микросекундах, против холодного старта контейнера, измеряемого в секундах, означает, что вы можете масштабировать до нуля без беспокойства о задержках для пользователей.
Почему так быстро?
Wasm-модули пропускают всю последовательность загрузки ОС. Нет инициализации ядра, монтирования файловой системы, загрузки динамических библиотек. Среда выполнения предварительно компилирует байткод Wasm в нативный машинный код (AOT-компиляция), а инстанциация — это просто выделение области линейной памяти и инициализация глобальных переменных.
Wasmtime 19 (март 2026) представил пулевое выделение экземпляров, которое предварительно выделяет пул слотов памяти. Инстанциация нового Wasm-модуля становится одним сдвигом указателя — буквально наносекунды.
Ландшафт облачных провайдеров
Каждый крупный облачный провайдер теперь предлагает Wasm-бессерверные среды, хотя уровень зрелости различается:
AWS Lambda Wasm Runtime (GA декабрь 2025)
AWS запустил нативную Wasm-среду выполнения для Lambda, отдельную от существующего контейнерного рантайма. Ключевые особенности:
- Поддержка WASI 0.3 через Wasmtime
- Субмиллисекундные холодные старты
- Поддержка Component Model для мультиязычных функций
- Интеграция с API Gateway, S3 events, SQS triggers
- Ценообразование: на 50% дешевле эквивалентного контейнерного Lambda
Google Cloud Run Wasm (GA февраль 2026)
Google выбрал другой подход, расширив Cloud Run для работы с Wasm-модулями наравне с контейнерами:
- Развёртывание
.wasm-компонентов напрямую черезgcloud run deploy --wasm - Автоматическое масштабирование до нуля с микросекундными холодными стартами
- Поддержка gRPC и HTTP/2 через WASI-сокеты
- Интеграция с Pub/Sub, Cloud Storage, BigQuery
Azure Container Apps Wasm (Preview, GA Q2 2026)
Microsoft интегрировал Wasm в Azure Container Apps через проект SpinKube:
- Kubernetes-нативный: Wasm-нагрузки работают рядом с контейнерами в одном кластере
- Spin Operator управляет жизненным циклом Wasm-компонентов
- KEDA-автомасштабирование с субсекундным откликом
- Azure Functions Wasm trigger (preview)
Граничные провайдеры
Cloudflare Workers поддерживает Wasm с 2018 года и полностью перешёл на WASI 0.3 в январе 2026. Fastly Compute запускает все нагрузки как Wasm-компоненты. Vercel Edge Functions добавил поддержку Wasm в конце 2025.
Рабочий процесс разработки на Rust + Wasm
Rust остаётся лучшим поддерживаемым языком для Wasm-разработки благодаря нулевым затратам рантайма и первоклассной поддержке цели wasm32-wasip2. Вот практический рабочий процесс:
Настройка проекта
# Установка WASI-цели
rustup target add wasm32-wasip2
# Создание нового проекта
cargo init --name my-service
# Добавление WASI-зависимостей
cargo add wit-bindgen
cargo add wasi --features "http,keyvalue,sql"
Сборка и тестирование
# Сборка Wasm-компонента
cargo build --target wasm32-wasip2 --release
# Локальный запуск через Wasmtime
wasmtime serve target/wasm32-wasip2/release/my_service.wasm
# Или через Spin
spin build && spin up
# Запуск тестов
cargo test --target wasm32-wasip2
Композиция компонентов
# Композиция двух компонентов в одно приложение
wasm-tools compose \
--definitions auth.wasm \
--definitions business_logic.wasm \
-o composed_app.wasm
# Просмотр интерфейсов компонента
wasm-tools component wit composed_app.wasm
Интеграция CI/CD
Типичный пайплайн GitHub Actions для Wasm:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-wasip2
- run: cargo build --target wasm32-wasip2 --release
- run: cargo test --target wasm32-wasip2
# Деплой в Fermyon Cloud
- uses: fermyon/actions/spin/deploy@v1
with:
fermyon_token: ${{ secrets.FERMYON_TOKEN }}
Контейнеры vs Wasm-модули: полное сравнение
Для команд, оценивающих Wasm наряду с существующей контейнерной инфраструктурой, вот детальное сравнение:
| Измерение | Контейнеры (Docker/OCI) | Wasm-модули (WASI 0.3) |
|---|---|---|
| Холодный старт | 500мс - 5с | 0.3мс - 3мс |
| Накладные расходы памяти | 50МБ - 500МБ базовые | 1МБ - 20МБ базовые |
| Размер бинарника | 50МБ - 2ГБ образы | 1МБ - 30МБ компоненты |
| Модель изоляции | Linux namespaces + cgroups | Wasm-песочница (memory-safe by design) |
| Языковая поддержка | Любые (запуск нативных бинарников) | Rust, Go, Python, JS, C/C++, C#, Kotlin |
| Сеть | Полный сетевой стек ОС | WASI-сокеты (TCP, UDP, TLS) |
| Файловая система | Полная POSIX-файловая система | Виртуальная ФС с ограничением по capabilities |
| Доступ к GPU | NVIDIA Container Toolkit | Экспериментальный (wasi-nn) |
| Зрелость экосистемы | 12+ лет, огромная экосистема | 3 года, быстро растёт |
| Оркестрация | Kubernetes, ECS, Nomad | SpinKube, wasmCloud, Kubernetes (через shim) |
| Инструменты отладки | Зрелые (strace, perf, gdb) | Улучшаются (wasm-tools, Wasmtime profiler) |
| Безопасность цепочки поставок | Сканирование образов, SBOM | SBOM на уровне компонентов, песочница по умолчанию |
| Лучше подходит для | Stateful-сервисы, ML-инференс, легаси | Бессерверные функции, edge-вычисления, плагины |
Когда использовать Wasm
- Бессерверные функции, где критична задержка холодного старта
- Edge-вычисления, где ограничены размер бинарника и память
- Системы плагинов, где нужно безопасное выполнение стороннего кода
- Мультитенантные платформы, где важна плотность изоляции (тысячи арендаторов на ноду)
- Полиглотные микросервисы, где команды используют разные языки
Когда остаться на контейнерах
- GPU-нагрузки (ML-обучение/инференс) — поддержка GPU в WASI пока экспериментальная
- Легаси-приложения, зависящие от конкретных возможностей ОС или библиотек
- Stateful-сервисы, которым нужно постоянное локальное хранилище
- Сложные сценарии отладки, где нужны полные инструменты уровня ОС
Кейсы из продакшена
Shopify: Edge Commerce
Shopify перевёл рендеринг витрин магазинов на Wasm на границе сети в 2025 году, обрабатывая 2.3 миллиона запросов в секунду через Cloudflare Workers. Результат: снижение TTFB на 68% для глобальных клиентов.
Midokura (Sony): IoT Gateway
Дочерняя компания Sony Midokura использует Wasm для запуска обработчиков протоколов устройств на IoT-шлюзах с 256МБ ОЗУ. Ранее каждый обработчик требовал отдельного контейнера. С Wasm они запускают 40 обработчиков протоколов в объёме памяти, который раньше поддерживал 4 контейнера.
Fermyon Platform: мультитенантный SaaS
Облачная платформа Fermyon запускает клиентские нагрузки как Wasm-компоненты с плотностью 12 000 экземпляров на ноду — плотность, невозможная с контейнерами. Средний холодный старт 0.8мс, а стоимость за запрос в 10 раз ниже, чем у эквивалентных Lambda-функций.
Модель безопасности
Модель безопасности Wasm принципиально отличается от контейнеров:
- Запрет по умолчанию — Wasm-модуль не может получить доступ ни к чему (файлам, сети, переменным окружения), пока хост явно не предоставит возможности
- Безопасность памяти — линейная память предотвращает выход переполнений буфера за пределы песочницы
- Нет ambient authority — в отличие от контейнеров (которые по умолчанию наследуют сетевое пространство имён хоста), Wasm-модули должны получать каждую возможность индивидуально
- Формальная верификация — спецификация Wasm достаточно проста для инструментов формальной верификации
Быстрый старт: ваш первый сервис на WASI 0.3
Вот минимальный HTTP-сервис на WASI 0.3 с Rust:
use wasi::http::proxy::export;
use wasi::http::types::{
IncomingRequest, OutgoingResponse, ResponseOutparam, Fields
};
struct MyService;
impl export::Guest for MyService {
async fn handle(request: IncomingRequest, response_out: ResponseOutparam) {
let headers = Fields::new();
headers.set(
&"content-type".to_string(),
&[b"application/json".to_vec()]
).unwrap();
let response = OutgoingResponse::new(headers);
response.set_status_code(200).unwrap();
let body = response.body().unwrap();
let writer = body.write().unwrap();
writer.write(b"{\"status\": \"ok\", \"runtime\": \"wasi-0.3\"}").await.unwrap();
ResponseOutparam::set(response_out, Ok(response));
}
}
export!(MyService);
Соберите, разверните — и у вас готов продакшен-сервис с микросекундными холодными стартами, memory-safe изоляцией и кросс-языковой композицией.
Часто задаваемые вопросы
WASI 0.3 готов к продакшену?
Да. WASI 0.3 — первая версия, которую Bytecode Alliance считает готовой к продакшену для серверных нагрузок. Wasmtime 19, WasmEdge 0.15 и все основные облачные рантаймы поддерживают его. Такие компании, как Shopify, Cloudflare и Fermyon, запускают WASI-нагрузки в масштабе.
Может ли Wasm заменить Kubernetes?
Не полностью. Wasm заменяет контейнерный рантайм для подходящих нагрузок, но оркестрация по-прежнему нужна. SpinKube и wasmCloud обеспечивают Kubernetes-нативную оркестрацию для Wasm-нагрузок, и многие команды запускают Wasm и контейнерные нагрузки бок о бок в одном кластере.
Как с драйверами баз данных?
Полная поддержка сокетов в WASI 0.3 означает, что нативные драйверы БД работают. Интерфейс wasi:sql предоставляет стандартизированный SQL API, а драйверы для PostgreSQL, MySQL и SQLite доступны как Wasm-компоненты. Клиенты Redis, NATS и Kafka также работают через WASI-сокеты.
Как WASI 0.3 управляет состоянием?
Wasm-модули по умолчанию stateless. Для состояния используйте wasi:keyvalue для key-value-хранилища, wasi:sql для реляционных данных или внешние сервисы через WASI-сокеты. Среда выполнения управляет бэкендами хранилищ — ваш код использует абстрактные интерфейсы.
Какова кривая обучения для Rust + Wasm?
Если вы уже знаете Rust, дополнительное обучение минимально — установите цель wasm32-wasip2 и изучите WIT-определения интерфейсов. Если Rust для вас новый, ожидайте 2-4 недели до продуктивной работы. Специфичные для Wasm концепции (Component Model, WIT, capabilities) добавляют ещё неделю.