Serverless-функции
Запускайте код по требованию без управления серверами: Lambda, edge-функции, триггеры и холодные старты.
За 30 секунд
Serverless-функции позволяют загрузить кусок кода, а облачный провайдер будет запускать его каждый раз, когда происходит событие: HTTP-запрос, загрузка файла, сообщение в очереди или расписание. Вы не управляете серверами, операционными системами или масштабированием; платформа запускает столько копий, сколько нужно, а вы платите за вызовы и время выполнения. Компромиссы — холодные старты, ограничения по времени и памяти и более тесная привязка к одному провайдеру.
Не в моём ежедневном стеке — я понимаю принципы и изучу детали, когда это понадобится проекту.
Почему это важно
- Команды используют serverless, чтобы выпускать небольшие API, вебхуки и фоновые задачи, не поднимая и не патча серверы.
- Он автоматически масштабируется от нуля до тысяч параллельных выполнений, что подходит для скачкообразного или непредсказуемого трафика.
- Оплата по факту использования делает нагрузки с низким или всплесковым трафиком очень дешёвыми по сравнению с постоянно включёнными машинами.
- Современные фронтенд-платформы (Vercel, Netlify, Cloudflare) запускают серверный код фреймворков, например API-роуты Next.js, как функции, так что большинство веб-разработчиков уже зависят от serverless, даже если так это не называют.
Как это работает
01Идея: функции вместо серверов
На классическом сервере ваше приложение работает постоянно, и вы платите за машину независимо от того, загружена она или нет. Serverless (точнее, Functions as a Service, FaaS) переворачивает это: вы деплоите функцию, платформа держит её в спящем состоянии, а когда приходит событие, запускает среду выполнения, выполняет ваш обработчик и позже замораживает или уничтожает её. Представьте такси вместо собственной машины: ни парковки, ни обслуживания, вы платите за поездку, но каждый раз немного ждёте подачи и следуете правилам таксопарка. «Serverless» не означает, что серверов нет; это значит, что серверы — проблема провайдера. Основные платформы — AWS Lambda, Google Cloud Run functions, Azure Functions и edge-платформы вроде Cloudflare Workers, Vercel Functions и Netlify Functions.
02Как вызов работает под капотом
Когда приходит событие и свободной тёплой среды нет, платформа делает холодный старт: создаёт micro-VM (Lambda использует Firecracker) или V8 isolate (Cloudflare Workers), скачивает ваш код, запускает рантайм и выполняет код инициализации вне обработчика. Затем вызывает обработчик с событием. После ответа среда какое-то время остаётся тёплой и может обслужить следующий запрос без затрат на init. В классической Lambda каждая среда обрабатывает один запрос за раз, так что 100 параллельных запросов означают 100 сред. Код на уровне модуля выполняется один раз на среду — именно там создают клиенты базы данных и загружают конфигурацию. Всё, что в памяти или в /tmp, может сохраниться между вызовами, но это никогда не гарантировано.
- Холодный старт: init + первый вызов, часто от 100 ms до более чем 1 с в зависимости от рантайма и размера пакета.
- Тёплый старт: только обработчик, обычно несколько миллисекунд накладных расходов.
- Concurrency: число сред, работающих в один и тот же момент.
03Пишем функцию для AWS Lambda
Функция Lambda — это обработчик, который получает event и context. Для HTTP её ставят за Function URL или API Gateway, который превращает HTTP-запрос в объект события, а возвращённое значение — обратно в ответ. Среди текущих управляемых рантаймов — Node.js 24 (nodejs24.x) и Python 3.14 на Amazon Linux 2023, на x86_64 или arm64 (Graviton, обычно дешевле). Память настраивается от 128 MB до 10,240 MB, и CPU масштабируется вместе с ней; максимальный таймаут — 15 минут; синхронные payload запроса и ответа ограничены 6 MB. Инициализируйте SDK-клиенты вне обработчика, чтобы тёплые вызовы переиспользовали их.
// index.mjs (runtime: nodejs24.x, handler: index.handler)
import { DynamoDBClient, GetItemCommand } from "@aws-sdk/client-dynamodb";
const db = new DynamoDBClient({}); // created once per environment
export const handler = async (event) => {
const id = event.pathParameters?.id;
if (!id) return { statusCode: 400, body: JSON.stringify({ error: "id required" }) };
const res = await db.send(new GetItemCommand({
TableName: process.env.TABLE_NAME,
Key: { pk: { S: `product#${id}` } },
}));
if (!res.Item) return { statusCode: 404, body: "{}" };
return { statusCode: 200, headers: { "content-type": "application/json" },
body: JSON.stringify({ id, name: res.Item.name.S }) };
};
04Триггеры событий: не только HTTP
Настоящая сила serverless — реакция на события по всему облаку. В AWS функция может запуститься, когда объект попадает в S3, сообщение приходит в SQS, строка меняется в DynamoDB Streams, срабатывает правило или расписание EventBridge или в поток Kinesis приходят записи. Вызовы бывают синхронными (вызывающий ждёт, как с HTTP), асинхронными (платформа ставит событие в очередь и повторяет при ошибке, с dead-letter назначением) или через event source mapping, который опрашивает очередь или поток и доставляет пачки. Поскольку асинхронные и очередные триггеры повторяют доставку, одно и то же событие может быть обработано больше одного раза: обработчики должны быть идемпотентными. Для пачек SQS сообщайте о частичных сбоях, чтобы повторялись только упавшие сообщения.
// SQS trigger with partial batch failures
// (enable ReportBatchItemFailures on the event source mapping)
export const handler = async (event) => {
const batchItemFailures = [];
for (const record of event.Records) {
try {
const job = JSON.parse(record.body);
await processOnce(job.id, job); // idempotent: skips already-done ids
} catch (err) {
console.error({ messageId: record.messageId, err: String(err) });
batchItemFailures.push({ itemIdentifier: record.messageId });
}
}
return { batchItemFailures };
};
05Edge-функции: код рядом с пользователем
Edge-функции работают во множестве точек по всему миру, рядом с пользователем, а не в одном регионе. Cloudflare Workers используют V8 isolate вместо контейнеров: isolate стартует за миллисекунды, поэтому холодные старты почти незаметны, но среда — это рантайм веб-стандартов (fetch, Request, Response, Web Crypto) с ограниченными API Node.js и более жёсткими лимитами CPU. Они идеальны для редиректов, проверок auth, A/B-тестов, переписывания заголовков, геолокации и лёгких API поверх edge-хранилищ (KV, D1, R2, Durable Objects). Для тяжёлой работы с базой далёкая база сводит выгоду на нет: edge-функция в Сиднее, вызывающая базу во Франкфурте, медленнее региональной функции рядом с базой. Functions в Vercel теперь по умолчанию используют рантайм Node.js с «Fluid compute», который позволяет одному инстансу обслуживать несколько параллельных запросов.
// Cloudflare Worker: geo-based redirect at the edge
export default {
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
const country = (request as any).cf?.country ?? "US";
if (url.pathname === "/" && country === "DE") {
return Response.redirect(new URL("/de", url).toString(), 302);
}
return fetch(request); // pass through to origin
},
};
06Деплой через infrastructure as code
Собирать функции кликами в консоли не масштабируется и не переживает смену команды. Описывайте функции, триггеры, права и окружение в коде: AWS SAM, Serverless Framework, AWS CDK, SST или Terraform. У каждой функции должна быть своя IAM-роль только с нужными правами. Секреты берутся из Secrets Manager или Parameter Store, а не из обычных переменных окружения в репозитории. Аккуратно пакуйте зависимости: меньшие бандлы стартуют быстрее, поэтому собирайте через esbuild и исключайте AWS SDK, если рантайм уже его предоставляет (рантаймы Node.js включают SDK v3).
# template.yaml (AWS SAM)
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Resources:
GetProduct:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs24.x
Architectures: [arm64]
Handler: index.handler
MemorySize: 512
Timeout: 10
Environment: { Variables: { TABLE_NAME: !Ref Products } }
Policies: [ { DynamoDBReadPolicy: { TableName: !Ref Products } } ]
Events:
Api: { Type: HttpApi, Properties: { Path: /products/{id}, Method: get } }
Products:
Type: AWS::Serverless::SimpleTable
07Стоимость, лимиты и когда это перестаёт быть дёшево
Lambda тарифицирует за запросы плюс GB-секунды (память, умноженная на длительность, с шагом 1 ms), с ежемесячным бесплатным лимитом. Для всплескового или низкого трафика это намного дешевле постоянно включённого сервера. Для стабильного высокого трафика постоянно работающая функция может стоить дороже контейнера или VPS, выполняющего ту же работу, а API Gateway, NAT-шлюзы и логирование часто стоят дороже самой функции. Следите за лимитами concurrency аккаунта (по умолчанию 1,000 на регион, можно повысить), reserved concurrency для защиты downstream-баз и таймаутами. Полезное правило: serverless идеален для «клеевого» кода событий, вебхуков, задач по расписанию и всплесковых API; долгие, нагруженные соединениями или стабильные нагрузки лучше подходят для контейнеров.
Когда применять
- Вебхуки, задачи по расписанию, обработка файлов и другой «клеевой» код, управляемый событиями.
- API со всплесковым, непредсказуемым или низким трафиком, где платить за простаивающие серверы расточительно.
- Edge-логика вроде редиректов, auth-шлюзов, A/B-тестов и персонализации, которая должна быть быстрой по всему миру.
- Небольшие команды, которые хотят управляемого масштабирования и патчинга и готовы к некоторой привязке к провайдеру.
Когда не стоит
- Долгие задачи дольше 15 минут, WebSocket-серверы или процессы, которым нужно постоянное состояние в памяти.
- Стабильные нагрузки с высокой пропускной способностью, где постоянно включённый контейнер или VPS дешевле и предсказуемее.
- Критичные к задержке пути, где редкие холодные старты недопустимы, а provisioned capacity слишком дорога.
Альтернативы
- VPS + Docker Compose
Предсказуемая стоимость и полный контроль; патчинг и масштабирование на вас, зато долгие процессы и WebSocket — просто.
- Serverless-контейнеры (Cloud Run, Fargate, Fly.io)
Запуск любого контейнера с автомасштабированием и меньшим числом ограничений рантайма, чем у функций.
- Kubernetes
Максимальный контроль для множества сервисов; гораздо больше операционной работы.
- Worker-ы очередей (BullMQ, Celery)
Фоновая обработка на своих серверах с тонким контролем над конкурентностью и повторами.
Лучшие практики
- Инициализируйте клиенты и конфигурацию вне обработчика и держите бандлы маленькими, чтобы сократить холодные старты.
- Делайте каждый обработчик идемпотентным; асинхронные и очередные триггеры доставляют at least once.
- Дайте каждой функции свою IAM-роль с минимальными правами и храните секреты в secrets manager.
- Задавайте явные таймауты и память; тестируйте размеры памяти, потому что больше памяти — это и больше CPU, что в итоге может оказаться дешевле.
- Используйте структурированные JSON-логи, трассировку (X-Ray или OpenTelemetry) и алерты на ошибки, throttling и длительность.
- Защищайте базы пулом соединений (RDS Proxy, serverless-драйвер) и reserved concurrency.
- Описывайте всё как infrastructure as code и деплойте через CI.
Частые ошибки
- Открытие нового соединения с базой на каждый вызов, что исчерпывает базу при первом всплеске трафика.
- Размещение функций в VPC с NAT-шлюзом только ради вызова публичных API, что без причины добавляет стоимость и задержку.
- Предположение, что состояние в памяти или в /tmp сохраняется между вызовами или что событие доставляется ровно один раз.
- Зацикливание рекурсивных триггеров (функция пишет в тот же S3-бакет, который её запускает).
- Игнорирование счёта за API Gateway, логи и передачу данных, который может превысить стоимость самой функции.
Глубже
08Внутри жизненного цикла среды выполнения
У среды выполнения Lambda три фазы. Init: платформа запускает расширения, рантайм и выполняет ваш код уровня модуля; у этой фазы свой лимит в 10 секунд. Invoke: обработчик выполняется для каждого события, по одному за раз в каждой среде. Shutdown: когда платформа утилизирует среду, расширения получают короткое окно, чтобы сбросить данные. Между вызовами среда заморожена, поэтому фоновая работа, запущенная без await (промис без await, таймер), может замереть на полпути и продолжиться в одном из следующих вызовов, что порождает запутанные баги. Всегда делайте await для всего перед возвратом или используйте response streaming, если нужно отправить байты пораньше. SnapStart, доступный для Java, Python и .NET, делает снапшот инициализированной среды и восстанавливается из него, поэтому уникальные значения вроде random seed и соединений нужно обновлять после восстановления.
09Конкурентность, масштабирование и throttling
Concurrency — это примерно число запросов в секунду, умноженное на среднюю длительность: 200 req/s при 250 ms требуют около 50 параллельных сред. В каждом регионе есть квота concurrency на уровне аккаунта, общая для всех функций, поэтому одна вышедшая из-под контроля функция может затроттлить остальные. Reserved concurrency задаёт для функции и гарантированную долю, и максимум, защищая хрупкие downstream-системы. Provisioned concurrency держит заданное число сред инициализированными, убирая холодные старты для этой ёмкости, за почасовую плату. При throttling синхронные вызывающие получают ошибки 429, а асинхронные события по умолчанию повторяются до шести часов. Для очередных триггеров maximum concurrency на event source mapping — более безопасный способ ограничить потребителей, чем reserved concurrency, из-за которой сообщения могут возвращаться в очередь.
# Cap a function at 50 concurrent executions
aws lambda put-function-concurrency \
--function-name get-product --reserved-concurrent-executions 50
# Keep 10 environments warm on the "live" alias
aws lambda put-provisioned-concurrency-config \
--function-name get-product --qualifier live \
--provisioned-concurrent-executions 10
10Тюнинг производительности: память, архитектура и бандлинг
В Lambda CPU выделяется пропорционально памяти; при 1,769 MB функция получает эквивалент одного полного vCPU. Поэтому увеличение памяти часто делает CPU-bound функции и быстрее, и дешевле: длительность падает сильнее, чем растёт цена. Измеряйте через AWS Lambda Power Tuning, который запускает функцию с несколькими размерами памяти и строит график стоимости против скорости. arm64 (Graviton) дешевле за GB-секунду и на многих нагрузках быстрее. Для Node.js собирайте бандл через esbuild, помечайте AWS SDK как external, используйте ES-модули с top-level await для инициализации и не импортируйте целиком SDK или ORM на холодных путях. Для Python урежьте зависимости и избегайте тяжёлых импортов на уровне модуля, если они не нужны в каждом вызове.
11Модель безопасности и типичные поверхности атак
IAM-роль выполнения каждой функции — это её идентичность; скомпрометированная функция может делать всё, что разрешает эта роль, поэтому ограничивайте её конкретными ресурсами и действиями. Данные событий — недоверенный ввод, даже если они приходят изнутри AWS: ключ объекта S3 или тело сообщения SQS могут нести payload для инъекции. Function URL с типом auth NONE доступны для вызова публично; используйте AWS_IAM auth или сами проверяйте подпись либо токен. Секреты нужно получать из Secrets Manager или Parameter Store с кэшированием (помогает AWS Parameters and Secrets Lambda Extension), а не вшивать в переменные окружения, видимые в консоли. Фиксируйте версии зависимостей и сканируйте их, потому что риск supply chain сосредоточен в небольших бандлах, которые уходят прямо в продакшен.
Реальные ситуации
Всплеск трафика положил базу
Проблема
Маркетинговая рассылка привела тысячи пользователей в API на Lambda и PostgreSQL. Lambda мгновенно масштабировалась, затем база упёрлась в лимит соединений, и все запросы стали падать.
Как решить
Во-первых, задайте reserved concurrency для API-функций на уровне, который выдерживает база, чтобы лишние запросы троттлились, а не роняли всё. Затем поставьте RDS Proxy (или PgBouncer) между функциями и базой для пула и мультиплексирования соединений и убедитесь, что клиенты создаются вне обработчика. Кэшируйте горячие эндпоинты чтения в CDN или Redis, чтобы большинство запросов вообще не доходило до базы. Наконец, перед следующей кампанией проведите нагрузочный тест с реалистичной конкурентностью и настройте алерты на throttling и число соединений с базой.
Дубли писем после деплоя
Проблема
Функция, запускаемая из SQS, отправляет письма с подтверждением заказа. После медленного сбоя у стороннего сервиса некоторые клиенты получили одно и то же письмо три раза.
Как решить
Функция не была идемпотентной: из-за таймаутов SQS снова делал сообщения видимыми и доставлял их повторно. Исправьте это, записывая ID каждого заказа в DynamoDB условным put (attribute_not_exists) перед отправкой; если запись не удалась, пропускайте отправку. Задайте таймаут функции меньше visibility timeout очереди (AWS рекомендует visibility как минимум в шесть раз больше таймаута функции), включите ReportBatchItemFailures, чтобы один сбой не повторял всю пачку, и подключите dead-letter queue с алертом, чтобы постоянные сбои разбирались, а не повторялись вечно.
Ресайз изображений при загрузке
Проблема
Продукту нужно генерировать миниатюры, когда пользователи загружают фото. Команда не хочет держать отдельный сервер-worker ради задачи, которая выполняется несколько сотен раз в день.
Как решить
Создайте S3-бакет для оригиналов с уведомлением о событии ObjectCreated, которое запускает функцию Lambda. Функция читает оригинал потоком, делает ресайз нативной библиотекой вроде sharp, собранной под arm64, и пишет миниатюры в другой бакет или префикс, чтобы избежать рекурсивных триггеров. Дайте ей 1-2 GB памяти для более быстрого CPU, таймаут 30 секунд и IAM-роль, ограниченную чтением из источника и записью в назначение. Отдавайте миниатюры через CDN. При таком объёме стоимость остаётся близкой к нулю, а патчить нечего.
Шпаргалка
- Вызвать задеплоенную функцию
aws lambda invoke --function-name fn --payload '{}' --cli-binary-format raw-in-base64-out out.json- Смотреть логи в реальном времени
aws logs tail /aws/lambda/fn --follow- SAM: сборка и деплой
sam build && sam deploy --guided- SAM: запуск локально
sam local invoke GetProduct -e event.json- Ограничить конкурентность
aws lambda put-function-concurrency --function-name fn --reserved-concurrent-executions 50- Создать публичный HTTPS URL (IAM auth)
aws lambda create-function-url-config --function-name fn --auth-type AWS_IAM- Cloudflare Worker: создать и задеплоить
npm create cloudflare@latest && npx wrangler deploy- Жёсткие лимиты Lambda
таймаут 15 мин, память 128 MB-10,240 MB, синхронный payload 6 MB, /tmp максимум 10 GB
Вопросы и ответы
Q1Что такое холодный старт и как его сократить?
Холодный старт происходит, когда нет доступной тёплой среды выполнения, и платформа должна создать её, загрузить ваш код, запустить рантайм и выполнить инициализацию до обработки запроса. Это может добавить от сотни миллисекунд до более чем секунды. Чтобы сократить: держите пакет деплоя маленьким за счёт бандлинга и tree-shaking, избегайте тяжёлых фреймворков на пути init, выбирайте быстро стартующий рантайм и лениво загружайте редко используемые модули. Где это действительно важно, используйте provisioned concurrency, чтобы держать среды тёплыми, или SnapStart на поддерживаемых рантаймах, чтобы восстанавливаться из снапшота. Edge-платформы на isolate по своей архитектуре в основном избегают холодных стартов.
Q2Как serverless-функции безопасно работают с реляционной базой?
Опасность — в количестве соединений: каждая параллельная среда открывает своё соединение, так что всплеск до 500 параллельных вызовов может попытаться открыть 500 соединений и исчерпать PostgreSQL или MySQL. Решения: поставить RDS Proxy или PgBouncer перед базой для пула соединений; использовать HTTP- или serverless-драйверы от провайдеров вроде Neon или PlanetScale; создавать клиент вне обработчика, чтобы тёплые вызовы его переиспользовали; ограничить конкурентность через reserved concurrency, чтобы функции не могли перегрузить базу. Также держите запросы короткими: долгие транзакции удерживают соединения из пула и снижают реальную ёмкость.
Q3Когда serverless дороже сервера?
Когда нагрузка стабильная и высокая. Функции тарифицируются за запрос и за GB-секунду, что отлично, когда трафик всплесковый или большую часть времени его нет, ведь простой ничего не стоит. Но если функция фактически занята круглосуточно, та же работа на контейнере или VPS обычно дешевле. Важны и скрытые расходы: плата API Gateway за запросы, почасовая плата и плата за трафик NAT-шлюза, приём логов в CloudWatch и межрегиональная передача часто превышают счёт за вычисления. Я считаю на реальных цифрах трафика и сравниваю общую стоимость, а не только цену функции.
Q4Что означает «at-least-once delivery» для проектирования функций?
Асинхронные вызовы, SQS, EventBridge и потоковые триггеры гарантируют, что событие будет доставлено, но при ошибках, таймаутах или внутренних повторах могут доставить его больше одного раза. Поэтому обработчики должны быть идемпотентными: двойная обработка одного события должна давать тот же эффект, что и однократная. Типичные приёмы — хранить ID обработанных событий с условной записью, использовать естественные ключи и upsert и передавать ключи идемпотентности платёжным провайдерам. Для постоянно повторяющихся сбоев настройте dead-letter queue или on-failure назначение, чтобы «отравленные» сообщения откладывались для разбора, а не повторялись вечно.
Q5Edge-функции или региональные: как выбирать?
Я смотрю, где живут данные и что нужно коду. Edge-функции работают рядом с пользователем и стартуют почти мгновенно, поэтому отлично подходят для редиректов, проверки auth-токенов, заголовков, A/B-тестов, геолокации и ответов из edge-хранилища или кэша. Но у них ограниченные рантаймы и время CPU, и если каждый запрос должен идти в базу в одном регионе, сетевые круги с далёких edge делают их медленнее региональной функции рядом с базой. Итак: edge — для лёгкой логики, которой мало нужно данных; региональные — для всего, что активно работает с базой или требует полного API Node.js.
Q6Как тестировать и отлаживать serverless-функции?
Я держу бизнес-логику в обычных модулях, которые покрываются юнит-тестами без всякого облака, а обработчики делаю тонкими: разобрать событие, вызвать логику, сформировать ответ. Для интеграции AWS SAM умеет локально вызывать функции с примерами событий и эмулировать API Gateway, а LocalStack эмулирует больше сервисов. Дальше каждый pull request деплоится в отдельный stage или аккаунт для настоящих end-to-end тестов. В продакшене обязательны структурированные JSON-логи с request ID, распределённая трассировка и алерты на ошибки, throttling и длительность, потому что подключиться к серверу и осмотреться нельзя.
Вопросы уровня senior
S1Спроектируйте serverless-пайплайн заказов, надёжный при частичных сбоях.
API-функция валидирует заказ, записывает его в DynamoDB с ключом идемпотентности от клиента и на том же шаге публикует событие OrderPlaced через DynamoDB Streams или transactional outbox, чтобы запись и событие не могли разойтись. EventBridge маршрутизирует событие в отдельные SQS-очереди для оплаты, склада и email, каждую из которых потребляет своя функция с отчётом о частичных сбоях пачки и dead-letter queue. Каждый потребитель идемпотентен по ID заказа. Для многошаговых потоков с компенсацией, например возврата денег при сбое на складе, Step Functions оркестрирует сагу с явными повторами и таймаутами. Наблюдаемость строится на correlation ID во всех функциях, а алерты следят за глубиной DLQ, долей ошибок и возрастом самого старого сообщения.
S2Как избежать vendor lock-in в serverless и стоит ли оно того?
Некоторая привязка — это цена выгоды, поэтому я решаю по слоям. Бизнес-логика живёт в обычных модулях без импортов провайдера, а обработчики — тонкие адаптеры; так самая дорогая часть остаётся переносимой. HTTP-функции могут использовать стандартные Request и Response через фреймворки вроде Hono, которые работают на Lambda, Workers, Node и Bun. Инфраструктура описана в Terraform или похожем инструменте, так что она хотя бы задокументирована и проходит ревью. Чего я не делаю — не оборачиваю каждый управляемый сервис в самописную абстракцию: переписывать очереди или маршрутизацию событий ради «cloud-agnostic» обычно дороже любой миграции. Реальный план выхода — контейнеризовать те же обработчики и перенести их на Cloud Run, Fargate или VPS, если изменятся цены или лимиты.
S3Когда бы вы увели нагрузку с Lambda и куда?
Сигналы такие: стабильно высокая загрузка, при которой цена за GB-секунды превышает стоимость контейнера; функции, приближающиеся к лимиту в 15 минут или требующие долгоживущих соединений вроде WebSocket или gRPC-стримов; тяжёлая инициализация на каждый запрос, которую наказывают холодные старты; или множество функций, разделяющих столько кода, что деплои становятся медленными и связанными. Обычная цель — serverless-контейнеры вроде Fargate или Cloud Run, которые сохраняют автомасштабирование и управляемую инфраструктуру, но снимают ограничения рантайма и позволяют много параллельных запросов на инстанс, или простой VPS с Docker Compose для предсказуемых нагрузок. Я бы сначала измерил, перенёс самый горячий путь, а «клеевой» код событий вроде вебхуков и задач по расписанию оставил на функциях, где он дешевле всего.
Глоссарий
- FaaS
- Functions as a Service: провайдер запускает ваши отдельные функции в ответ на события и берёт плату за использование.
- Холодный старт
- Дополнительная задержка, когда перед обработкой запроса нужно создать и инициализировать новую среду выполнения.
- Среда выполнения
- Изолированная micro-VM или isolate, в которой работает функция; её могут переиспользовать для следующих вызовов.
- Concurrency
- Сколько вызовов функции выполняется в один и тот же момент, каждый в своей среде.
- Provisioned concurrency
- Заранее инициализированные среды, которые держатся тёплыми за плату и убирают холодные старты для этой ёмкости.
- Event source mapping
- Ресурс Lambda, который опрашивает очередь или поток и вызывает вашу функцию с пачками записей.
- Dead-letter queue
- Очередь, куда откладываются постоянно падающие события для последующего разбора вместо бесконечных повторов.
- V8 isolate
- Лёгкая песочница внутри одного процесса JavaScript-движка; стартует за миллисекунды и лежит в основе edge-платформ.
- Идемпотентность
- Свойство операции давать один и тот же эффект, выполняется ли она один раз или несколько раз с одинаковым вводом.
Что изучить дальше
Есть идея продукта?Давайте создадим его.
Расскажите о своей идее, продукте или команде. Обычно отвечаю в течение одного рабочего дня.