Как запустить Durable Objects от Cloudflare на своих серверах с помощью celld

08 авг 2026
4,581
166
21
5 дней

Райан Даль и команда Deno тихо выложили в опенсорс проект celld. Если вы когда-нибудь завидовали пользователям Cloudflare из-за их концепции Durable Objects, но не хотели связываться с вендорлоком, эта штука может вас заинтересовать.

celld — это демонический рантайм на Rust, который умеет запускать бандлы Cloudflare Workers и изолированные инстансы Durable Objects на вашем собственном железе. Без Etcd, без Raft и без громоздких сервисов координации.

В чём соль концепции

Традиционный бекенд обычно делится на stateless-микросервисы и одну большую реляционную базу данных. Когда нагрузка растёт, база неизбежно становится главным узким местом.

Cloudflare предложила другой подход. Каждый активный сущностный объект приложения (например, чат-комната, корзина покупателя или сессия документа) получает собственный V8-изолят и персональную базу данных SQLite. Объект оживает при поступлении запроса, держит состояние в памяти и локальном файле SQLite, а при простое просто засыпает.

Главная проблема заключалась в замкнутости экосистемы: запустить такую схему за пределами инфраструктуры Cloudflare до сих пор было практически невозможно.

Реклама

Как устроен celld изнутри

Разработчики celld пошли по пути радикального упрощения. Архитектура ноды состоит из четырех компонентов:

  1. Встроенный V8 для выполнения JavaScript и TypeScript кода из бандлов Wrangler.
  2. Локальный SQLite для отдельного файла БД каждого объекта.
  3. S3-совместимое хранилище (AWS S3, MinIO, Cloudflare R2) в качестве единственного источника правды.
  4. Межсерверный транспорт с HMAC-подписью для обмена данными между нодами.

Самое интересное решение здесь — отказ от классических протоколов консенсуса. Нодам в кластере не нужно выбирать лидера или держать запущенный Consul.

Вместо этого сервера общаются с S3 через атомарную операцию Compare-And-Swap (CAS). Когда нода хочет забрать себе обслуживание объекта, она записывает файл владения в S3-бакет. Кто успел обновить запись через CAS, тот и обрабатывает трафик. Если нода падает, таймаут записи истекает, а соседний сервер подхватывает объект, скачивает его свежую SQLite-базу из бакета и продолжает работу.

Запуск и развёртывание

Для сборки проекта подходят обычные сборки Wrangler, но на сервере понадобится esbuild и сам бинарник celld.

Установка выполняется одной командой:

curl -fsSL https://celld.dev/install.sh | sh

Процесс работы разделен на два этапа. Сначала загружаем сборку воркера в бакет:

celld deploy . \
  --bucket s3://my-cells-bucket

Затем запускаем демона на сервере:

celld \
  --bucket s3://my-cells-bucket \
  --listen 0.0.0.0:8080 \
  --advertise 10.0.0.12:8080

Каждый узел в кластере читает манифест deploy/current.json из бакета. Если нужно поднять дополнительный сервер, вы запускаете ещё один процесс с тем же бакетом и указываете его сетевой адрес в --advertise.

По поводу безопасности: межсерверный трафик celld не шифрует TLS из коробки. Авторы рекомендуют убирать внутренние порты нод под защищенную оверлейную сеть вроде WireGuard или Tailscale. Все peer-запросы автоматически подписываются HMAC-ключом fleet/peer-auth.json, который первая нода автоматически создаёт в бакете.

Диагностика и управление нагрузкой

Для мониторинга кластера есть утилита diagnose. Она опрашивает соседей и показывает текущие метрики:

celld diagnose --bucket s3://my-cells-bucket

Команда выведет потребление CPU, RSS-памяти, количество активных WebSocket-подключений и число живых объектов на каждом узле.

Если сервер начинает перегружаться, в celld предусмотрен механизм сброса активных объектов (pressure shedding). Лимиты задаются через переменные окружения:

CELLD_MAX_RESIDENT_CELLS=1000 \
CELLD_RESIDENT_LOW_WATER=800 \
celld --bucket s3://my-cells-bucket --listen 0.0.0.0:8080 \
  --advertise node-a.internal:8080

При превышении порога celld сохраняет неактивные объекты в S3, снимает с себя права владения и перестает принимать новые сущности, пока нагрузка не спадет до значения CELLD_RESIDENT_LOW_WATER. Объекты с частыми запросами или открытыми WebSocket-соединениями при этом не затрагиваются.

Необычный подход к контрибьютингу

Если вы зайдёте в репозиторий denoland/celld с намерением открыть Pull Request, кнопка окажется недоступна. Форки разрешены, а вот PR на GitHub отключены полностью.

Райан Даль объясняет это борьбой со спамом от ИИ-агентов: разбор гигантских автосгенерированных пулл-реквестов без контекста отнимает у мейнтейнеров слишком много времени. Желающим прислать патч предлагают делать git format-patch и отправлять файл письмом на личную почту ry@deno.com.

Кому стоит присмотреться к проекту

Проект находится в активной фазе разработки, спецификации протокола хранятся прямо в коде Rust-крайта crates/celld/protocol.rs. Тащить его в критичный продакшен пока рано, но поэкспериментировать точно стоит.

Инструмент пригодится в следующих случаях:

  1. Разработчикам мультиплеерных сервисов, чатов и кастомных CRM.
  2. Командам, планирующим уйти от привязки к Cloudflare без переписывания кода.
  3. Поклонникам архитектуры с отдельной базой данных на каждого клиенто-пользователя.
  4. Инженерам, изучающим распределённые системы без Raft и Etcd.

🍪 Мы используем файлы cookie и сервис аналитики Яндекс.Метрика, чтобы сайт работал лучше. Продолжая пользоваться devtrends.ru, вы соглашаетесь с обработкой данных согласно Политике конфиденциальности.