Перейти к основному содержимому
DevOpsMar 28, 2026

WASI 0.3 и смерть холодных стартов: серверный Wasm в продакшене

OS
Open Soft Team

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 LambdaWasm-модуль (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 + cgroupsFirecracker microVMWasm-песочница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 + cgroupsWasm-песочница (memory-safe by design)
Языковая поддержкаЛюбые (запуск нативных бинарников)Rust, Go, Python, JS, C/C++, C#, Kotlin
СетьПолный сетевой стек ОСWASI-сокеты (TCP, UDP, TLS)
Файловая системаПолная POSIX-файловая системаВиртуальная ФС с ограничением по capabilities
Доступ к GPUNVIDIA Container ToolkitЭкспериментальный (wasi-nn)
Зрелость экосистемы12+ лет, огромная экосистема3 года, быстро растёт
ОркестрацияKubernetes, ECS, NomadSpinKube, wasmCloud, Kubernetes (через shim)
Инструменты отладкиЗрелые (strace, perf, gdb)Улучшаются (wasm-tools, Wasmtime profiler)
Безопасность цепочки поставокСканирование образов, SBOMSBOM на уровне компонентов, песочница по умолчанию
Лучше подходит для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) добавляют ещё неделю.