← Containers / containers
Жизненный цикл контейнера
Развёртывание
После деплоя приложения с Container ваш образ загружается в Cloudflare Registry и распространяется по всей сети Cloudflare. Cloudflare заранее планирует экземпляры и предварительно загружает образы по всему миру, чтобы обеспечить быстрый запуск при увеличении числа одновременно работающих экземпляров контейнеров.
Код Worker вступает в силу сразу после развёртывания. Экземпляры контейнера обновляются с развертывание. См. Развертывание Containers.
Жизненный цикл запроса
От клиента к Worker
Напомним, что в основе Containers лежат Durable Objects и Workers. Запросы сначала направляются через Worker, который обычно обрабатывается дата-центром в местоположении с наилучшей задержкой между собой и запрашивающим пользователем. Для оптимизации общей задержки может быть выбран другой дата-центр, если Smart Placement включён, либо если ближайшая локация испытывает высокую нагрузку.
Поскольку все запросы к Container проходят через Worker, конечные пользователи не могут отправлять к экземпляру Container не-HTTP запросы по TCP или UDP. Если вам нужен сценарий с входящими TCP или UDP от конечного пользователя, сообщите нам ↗.
От Worker к Durable Object
Из Worker запрос проходит через экземпляр Durable Object ( Класс Container расширяет класс Durable Object). Каждый экземпляр Durable Object представляет собой глобально маршрутизируемый изолят, который может выполнять код и хранить состояние. Это позволяет разработчикам легко адресовать конкретные экземпляры контейнеров и направлять к ним запросы (независимо от того, где они размещены), определять и запускать хуки при изменении статуса контейнера, выполнять периодические проверки экземпляра и хранить постоянное состояние, связанное с каждым экземпляром.
Запуск Container
Когда экземпляр Durable Object запрашивает запуск нового экземпляра контейнера, ближайшая локация с предварительно загруженным образом выбрано.
Запуск дополнительных экземпляров контейнера использует другие локации с заранее загруженными образами, и Cloudflare автоматически начинает незаметно подготавливать дополнительные машины для дальнейшего масштабирования и быстрого холодного старта. Поскольку количество прогретых локаций ограничено, некоторые экземпляры контейнера могут запускаться в локациях, которые находятся дальше от конечного пользователя. Это делается для того, чтобы экземпляр контейнера запускался быстро. Вы оплачиваете только активно работающие экземпляры, а не неиспользуемые прогретые образы.
Холодный старт
Холодный старт происходит, когда экземпляр контейнера запускается из полностью остановленного состояния.
Если вы вызываете env.MY_CONTAINER.get(id) с совершенно новым ID и запускаете
этот экземпляр впервые, произойдёт холодный старт.
При этом образ контейнера впервые запустится со своей точки входа. В зависимости
от того, что делает эта точка входа, запуск может занять разное время.
Холодный старт Container часто занимает от 1 до 3 секунд, но это зависит от размера образа, времени выполнения кода и других факторов.
Запросы к запущенным Containers
Когда запрос запускается новый экземпляр контейнера, выбирается ближайшая локация, где образ уже предварительно загружен. Последующие запросы к конкретному экземпляру, независимо от того, откуда они поступают, будут направляться в эту локацию, пока экземпляр остаётся активным.
Однако после остановки и перезапуска этого экземпляра контейнера последующие запросы могут направляться в другой локации. Эта локация снова будет ближайшей к исходному запросу локацией с уже загруженным образом.
Среда выполнения контейнера
Каждый экземпляр контейнера выполняется в собственной виртуальной машине, которая обеспечивает надёжную
изоляцию от других нагрузок, работающих в сети Cloudflare. Контейнеры
следует создавать для linux/amd64 архитектуру и должен укладываться в границы
ограничения по размеру.
Логирование, сбор метрик и сеть настраиваются автоматически на каждом контейнере в соответствии с настройками разработчика.
Остановка Container
Класс Container задаёт sleepAfter до 10 минут по умолчанию. Его значение по умолчанию onActivityExpired() реализация сигнализирует контейнеру об остановке после указанного периода бездействия. Вы можете изменить длительность или переопределить хук.
Вы можете самостоятельно остановить экземпляр контейнера с помощью stop() или destroy().
Перед остановкой экземпляра контейнера платформа выполняет следующее:
- Отправляет
SIGTERMосновному процессу в контейнере. - Ожидает завершения этого процесса до 15 минут.
- Отправляет
SIGKILLесли процесс ещё выполняется.
Обработка SIGTERM в образе, если вам требуется очистка перед завершением. Та же последовательность выполняется, когда развертывание заменяет экземпляр контейнера новым образом.
Хуки жизненного цикла
Container класс предоставляет хуки, которые выполняют код Worker при изменении состояния контейнера:
onStart(): Выполняется после запуска контейнера.onStop(): Выполняется после завершения процесса контейнера. Получает код завершения и причину остановки.onActivityExpired(): Выполняется, когдаsleepAfterтаймер истекает без входящих запросов. Реализация по умолчанию вызываетstop()чтобы завершить работу контейнера. Это можно использовать, чтобы останавливать контейнер только при определённых условиях.onError(): Выполняется, когда контейнер завершается с ошибкой.
См. пример хуков статуса для полной реализации.
Постоянный диск
Весь диск временный. Когда экземпляр Container переходит в спящий режим, при следующем запуске он получает новый диск, определяемый образом контейнера.
Снапшоты появятся в ближайшее время: они позволят пользователю быстро сохранять и восстанавливать диск из всего контейнера или из отдельного каталога.
Также можно использовать FUSE для сохранения диска в R2 или другое объектное хранилище. Однако при использовании FUSE не ожидайте нативной производительности на уровне SSD.
Пример запроса
- Разработчик развёртывает Container, а Cloudflare автоматически подготавливает экземпляры по всей своей сети.
- Клиент в Барилоче, Аргентина, отправляет запрос. Он поступает на Worker в ближайшей локации Cloudflare в Неукене, Аргентина.
- Этот запрос Worker вызывает
getContainer(env.MY_CONTAINER, "session-1337"). Под капотом это запускает Durable Object, который затем вызываетthis.ctx.container.start. - Это запрашивает ближайший свободный экземпляр Container. Cloudflare определяет, что свободный экземпляр есть в Буэнос-Айресе, Аргентина, и запускает его там.
- Другому пользователю нужно попасть в тот же контейнер. Его запрос поступает на Worker, который выполняется в локации Cloudflare в Сан-Диего, США.
- Worker снова вызывает
getContainer(env.MY_CONTAINER, "session-1337"). - Если исходный экземпляр контейнера всё ещё работает, запрос направляется в исходное местоположение в Буэнос-Айресе. Если исходный контейнер перешёл в спящий режим, Cloudflare снова попытается найти ближайший «свободный» экземпляр Container, вероятно, в Северной Америке, и запустит там новый экземпляр.