Serverless и Edge Functions: где ломается классический бэкенд
Самое узкое место в обработке запросов проявляется не в среднем дне, а на пике. Классический серверный бэкенд считают по пиковой нагрузке: пул воркеров, соединений и памяти держат с запасом под редкие всплески, и всё остальное время этот запас простаивает. Как только трафик подскакивает в разы, свободные обработчики заканчиваются — начинается перегрузка при пиках.
Дальше работает накопительный эффект: очередь запросов растёт, деградация отклика идёт лавиной — время ответа уходит с доли секунды на секунды, 95-й процентиль рвётся вверх, а часть обращений падает по таймауту ещё до входа в бизнес-логику. Пользователь видит не «медленно», а «не работает», и уходит. Для владельца сервиса это потерянные заказы, а не строчка в логах, и разбираться в ней начинают уже после инцидента.
Горизонтальный автоскейлинг закрывает это лишь отчасти: новый экземпляр поднимается минуты, прогревает кеш и открывает соединения к базе, у которой свой предел — масштабируя приложение, мы упираемся в пул соединений и общие блокировки. Пик успевает пройти раньше, чем инфраструктура на него отреагирует.
Serverless и Edge Functions снимают именно это ограничение: обработчик запускается под каждый запрос и масштабируется по факту нагрузки, без прогрева и постоянного резерва. Ниже разбираем, как это закрывается на практике — и где классический бэкенд по-прежнему остаётся правильным выбором.
Что даёт периферийная обработка запросов
Периферийная обработка переносит выполнение логики ближе к посетителю: обработчик запускается на узле сети рядом с ним, а не в единственном центре обработки данных. Ниже — четыре эффекта, которые видно в метриках, а не в формулировках.
Время отклика на распределённых запросах
Значительная часть времени ответа — не вычисления, а сетевые круги между посетителем и сервером. Когда функция выполняется на ближайшем узле, каждый круг сокращается, и на цепочке из нескольких обращений это складывается в заметную разницу для пользователя. Независимые замеры задержек между регионами публикует M-Lab — их открытые измерения удобно брать точкой отсчёта, когда выбираешь, где размещать обработчики.
Устранённые классы отказов при пиковой нагрузке
Очередь входящих запросов, исчерпание пула соединений к базе, отказ площадки целиком — при периферийной схеме эти классы отказов перестают быть системными. При деградации отдельного узла трафик уходит на соседний, и простой измеряется секундами, а не временем ручного переключения записи.
Масштабирование под пики берёт на себя платформа: экземпляры обработчиков добавляются под фактический поток и снимаются, когда он спадает. Постоянный резерв под худший день недели больше не нужен — он превращается в запас по квотам.
Выделенный сервер, Serverless и периферийные функции: сравнение
Модель исполнения задаёт три вещи: как приложение переживает пик нагрузки, сколько времени занимает выпуск изменения и какие отказы вообще возможны. Выделенный сервер предсказуем, но простаивает на спадах; периферийные функции откликаются быстро, но живут в урезанной среде. Выбор здесь не про «что современнее», а про то, что упирается в вашем случае.
Ниже — альтернативы, между которыми реально выбирают на этапе проектирования, и их ограничения.
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Постоянный выделенный сервер | Ровный поток, долгие соединения, фоновые задачи | Простой на спадах, масштабирование вручную, обновления на вас |
| Контейнер | Нужен контроль над средой без привязки к железу | Холодный старт, нужны оркестратор и лимиты |
| Серверные функции | Рваная нагрузка, вебхуки, обработка событий | Лимит времени выполнения, нет постоянного состояния |
| Периферийные функции | Персонализация, маршрутизация, отклик ближе к пользователю | Урезанная среда, лимиты памяти, нет тяжёлых библиотек |
| Гибридная схема | Витрина на функциях, ядро и очереди — на сервере | Сложнее отладка и трассировка, нужны единые правила выпуска |
Когда выгодна гибридная схема
Гибридная схема имеет смысл, когда у приложения два разных профиля нагрузки: отклик на действие пользователя и фоновая обработка. Витрину, авторизацию и маршрутизацию отдаём периферийным функциям, события и очереди — серверным, а базу, поиск и тяжёлые расчёты держим на постоянном сервере или в контейнерах. Граница проходит по состоянию: чем ближе функция к данным, тем меньше выигрыш от её выноса.
Как мы разворачиваем серверную логику: этапы работ
Развёртывание серверной логики начинается не с кода, а с инвентаризации того, что уже работает. Снимаем профиль нагрузки на реальном трафике: какие маршруты вызываются чаще всего, где держится соединение с базой, какие операции упираются в холодный запуск. Только после этого решаем, что уходит в управляемые функции, а что остаётся на постоянных процессах.
Аудит и схема
- Аудит бэкенда и профиль нагрузки — карта обработчиков, пиковые запросы, длительность ответа, доля повторных обращений. Цифры показывают, где функция окупает себя, а где добавит задержку.
- Схема развёртывания — раскладываем маршруты по зонам выполнения, фиксируем точки отказа и поведение приложения при недоступности внешнего сервиса.
- Настройка окружений и баз — раздельные контуры, порядок миграций, доступы и секреты вне репозитория, лимиты времени выполнения для каждой функции.
Настройка, проверка, передача
- Перенос логики и подключение хранилищ — пошагово и с обратной совместимостью: старый и новый контур работают параллельно, трафик переключается долями.
- Проверка под нагрузкой и на отказ — прогон на профиле, снятом на первом этапе, плюс отключение базы и внешних сервисов. Смотрим, как восстанавливается очередь и не теряются ли события.
- Ввод в эксплуатацию и передача — включаем наблюдаемость, оповещения по ошибкам и задержкам, отдаём схему, конфигурации и регламент отката.
Что остаётся в вашем репозитории после сдачи
После запуска проект остаётся у вас не «чёрным ящиком», а рабочим репозиторием, который читается и воспроизводится вашей командой. Это касается и приложений на функциях (Serverless и Edge Functions): мы передаём не набор файлов «как получилось», а описание среды, связей и правил эксплуатации.
Ниже — обязательный минимум, который переходит вам при сдаче:
- Конфигурации окружений — разработка, тестовый контур, рабочая среда: один и тот же код разворачивается предсказуемо, различия только в параметрах.
- Схемы маршрутизации запросов — какой путь и домен куда ведёт, где включается кэширование, какие правила работают на ближнем к пользователю узле, а какие на серверной стороне.
- Политики доступа и роли — кто и что может менять, как выдаются и отзываются ключи, как разделены права вашей и подрядной команды.
- Описание переменных окружения — таблица с назначением каждой, обязательностью, форматом значения и перечнем мест, где она используется.
- Документация — локальный запуск, состав сервисов, точки интеграций, порядок выпуска новой версии и признаки типовых сбоев.
- Регламент обновления и отката — как выпустить изменение и как вернуться на предыдущую версию, что при этом происходит с данными.
Схемы и регламенты
Схемы хранятся рядом с кодом и обновляются вместе с ним, а не живут в переписке. Регламент обновления и отката проверяется на тестовом контуре до передачи: инженер, который раньше не касался проекта, поднимает копию окружения и откатывает выпуск по документу, без уточнений с нашей стороны.
Кейс: пиковая нагрузка во время распродаж
Заказчик — розничный магазин с резкими пиками: в дни распродаж поток обращений вырастал десятикратно в течение часа. Витрина жила на двух серверах с фиксированным потолком, и при выходе за него каталог начинал отдавать ошибки, корзина теряла позиции, а инженеры вручную поднимали новые узлы и ждали прогрева кэша.
Добавлять серверы «накануне» не помогало: точную минуту пика не угадать, часть ресурсов простаивала, часть не успевала включиться в работу. Мы разобрали, где именно терялось время на пути запроса, и перераспределили нагрузку по слоям.
Метрики до и после
| Показатель | До | После |
|---|---|---|
| Время отклика каталога на пике | секунды, рост с каждой минутой всплеска | стабильные десятые доли секунды |
| Доля ошибок при десятикратном всплеске | около 4% запросов | ниже 0,1% |
| Время восстановления после сбоя | часы ручных действий | минуты, автоматически |
| Подготовка к распродаже | ночные работы с остановкой витрины | без остановки, поэтапно |
Витрину и персонализированные блоки отдаём ближе к пользователю, а оформление заказа, оплату и письма вынесли в асинхронную обработку с очередью и повторами. Новые экземпляры приложения включаются за секунды, поэтому десятикратный всплеск гасится сам, без дежурства у мониторов.
Порядок цифр подтверждают публичные замеры: Cloudflare публикует открытую статистику по разнице между отдачей с периферии и из одного центра — radar.cloudflare.com. Для заказчика это значит, что распродажа перестала быть аварийным режимом: приложение держит пик, а команда занимается развитием, а не тушением.
Чем периферийная функция отличается от серверной
Точка исполнения кода задаётся платформой, а не кодом. Серверная функция разворачивается в выбранном регионе: запрос пользователя идёт по сети до этого региона и только там начинает обрабатываться. Периферийная функция исполняется в узле, ближайшем к пользователю, — сетевой путь сокращается с сотен миллисекунд до десятков, и это видно на времени до первого байта ответа.
Время запуска у них разное по природе. Серверная функция живёт в контейнере, который платформа останавливает при простое: первый запрос после паузы получает холодный запуск и добавляет к отклику десятки и сотни миллисекунд. Периферийные среды держат изоляты прогретыми, поэтому запуск там измеряется единицами миллисекунд, но в обмен на жёсткие лимиты по длительности исполнения и объёму памяти.
Данные рядом с пользователем — только лёгкие: заголовки запроса, геоданные по адресу, кэш статики, реплики хранилищ ключ-значение. Основная база остаётся в регионе, и если периферийная функция делает к ней синхронный запрос, выигрыш по задержке съедается обратной дорогой. Поэтому решение принимают по данным, а не по вкусу.
На периферию не выносят длительные вычисления, транзакции с несколькими записями, работу с файлами и фоновые задачи. Тяжёлые зависимости и нативные модули увеличивают размер сборки и время запуска, а состояние между запросами там не сохраняется предсказуемо. Бизнес-логика, доступ к базе и интеграции остаются на серверных функциях.
На периферии держат проверку токена, редиректы, персонализацию заголовков, раздачу кэша и разбиение трафика. Граница проходит по простому признаку: если ответ собирается из данных, лежащих рядом с пользователем, — это периферия; если нужен полный контекст из базы, — серверная функция.
Технические сомнения перед стартом
Сомнения на старте почти всегда одинаковые — и обоснованные. Пять вопросов ниже мы разбираем до первой строки конфигурации: в serverless-модели именно ответы на них определяют архитектуру, а не наоборот.
Сможем ли вернуть нагрузку на постоянный сервер?
Да, обратный перенос закладываем сразу: логика живёт в переносимых обработчиках, работа с хранилищем идёт через собственные интерфейсы. Переезд занимает дни, а не месяцы.
Можно ли запустить гибридно — часть маршрутов оставить у себя?
Да. Админку, отчёты и тяжёлые фоновые задачи держим на постоянных серверах, на периферию отдаём публичные страницы и обработчики внешних событий.
Где хранятся ключи и секреты?
В защищённом хранилище, подстановка — в момент вызова: в репозиторий и переменные сборки они не попадают. Доступ по ролям, ротация ключей, журнал обращений.
Как приложение работает с базой из разных регионов?
Чтение — из ближайшей реплики, запись — в основную базу, соединения идут через пул. Для операций со строгой согласованностью оставляем один регион — это ограничение проговариваем до старта.
Кто отвечает за откат изменений?
Мы. Версии неизменяемы и помечены, откат — переключение трафика на предыдущую за минуты. Схема базы меняется только с обратными миграциями, проверенными на копии.
Обсудим задачу и вернёмся с оценкой
Чтобы оценка опиралась на ваш контур, а не на типовой шаблон, достаточно первичного набора вводных — часть данных обычно уже есть в репозитории и панели наблюдаемости. Пришлите то, что под рукой, остальное уточним в разговоре.
- схему текущего бэкенда: какие сервисы есть, что живёт в одном процессе, где хранится общее состояние;
- профиль нагрузки: пиковые запросы в секунду, суточный и недельный ритм, сезонные всплески;
- перечень маршрутов и их характер: отдача статики, чтение из базы, тяжёлые вычисления, обращения к внешним системам;
- ограничения по данным: где им разрешено находиться, требования к шифрованию, срокам хранения и удалению;
- требования к доступности: допустимое время недоступности и приоритет между регионами;
- ограничения со стороны: что нельзя менять в контрактах для мобильных клиентов и партнёрских интеграций;
- доступы: репозиторий, тестовая среда, панель наблюдаемости, права на чтение схем конфигурации.
По этим вводным разберём, какие маршруты переносятся в бессерверный контур и вычисления на границе сети, а какие остаются на постоянных процессах — обычно это фоновые задачи и длительные соединения. Вернёмся с оценкой работ и планом внедрения: очередность переноса, точки отката на каждом шаге, состав проверок и порядок переключения трафика. Опишите задачу — обсудим детали и договоримся о разговоре.







