AWS Lambda: serverless

AWS Lambda — serverless-сервис для запуска кода без управления серверами: функция запускается по событию, выполняется и останавливается, оплата только за фактическое время выполнения.

Зачем нужно

Lambda избавляет от необходимости держать работающий сервер 24/7 для редких задач. Нужно обрабатывать загруженные изображения, отправлять email по расписанию, реагировать на события S3? Lambda запустится, выполнит задачу и остановится — оплата только за миллисекунды работы. Первые 1 млн вызовов в месяц бесплатны.

Где используется

  • Обработка изображений при загрузке в S3 (resize, watermark)
  • Webhook-обработчики (GitHub, Stripe, Telegram Bot)
  • Scheduled-задачи по cron (очистка данных, отчёты)
  • API backend через API Gateway
  • Обработка событий из SQS, Kinesis

Основной контент

Структура Lambda-функции (Node.js)

// handler.js
exports.handler = async (event, context) => {
  console.log('Event:', JSON.stringify(event, null, 2));

  try {
    // Бизнес-логика
    const result = await processEvent(event);

    return {
      statusCode: 200,
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ success: true, data: result }),
    };
  } catch (error) {
    console.error('Error:', error);
    return {
      statusCode: 500,
      body: JSON.stringify({ error: error.message }),
    };
  }
};

Деплой через AWS CLI

# Создать zip-архив
zip -r function.zip handler.js node_modules/

# Создать функцию
aws lambda create-function \
  --function-name my-function \
  --runtime nodejs20.x \
  --role arn:aws:iam::123456789:role/lambda-role \
  --handler handler.handler \
  --zip-file fileb://function.zip \
  --timeout 30 \
  --memory-size 256

# Обновить код
aws lambda update-function-code \
  --function-name my-function \
  --zip-file fileb://function.zip

# Тест вызова
aws lambda invoke \
  --function-name my-function \
  --payload '{"key":"value"}' \
  output.json()

Serverless Framework (упрощённый деплой)

# serverless.yml
service: my-api

provider:
  name: aws
  runtime: nodejs20.x
  region: eu-west-1
  environment:
    DATABASE_URL: ${env:DATABASE_URL}

functions:
  api:
    handler: handler.handler
    events:
      - httpApi:
          path: /api/{proxy+}
          method: ANY
  scheduled:
    handler: jobs.cleanup
    events:
      - schedule: cron(0 2 * * ? *)   # каждый день в 02:00 UTC
npm install -g serverless
serverless deploy

Обработчик событий S3

// Вызывается при загрузке файла в S3
exports.handler = async (event) => {
  for (const record of event.Records) {
    const bucket = record.s3.bucket.name;
    const key = decodeURIComponent(record.s3.object.key.replace(/\+/g, ' '));
    console.log(`New file: s3://${bucket}/${key}`);
    // обработать файл...
  }
};

Cold Start

Lambda-функция «засыпает» при отсутствии трафика. При первом вызове после паузы — cold start (100ms–1s). Способы уменьшить:

  • Использовать Provisioned Concurrency (платно)
  • Держать функцию «тёплой» через scheduled ping
  • Выбирать runtime с быстрым холодным стартом (Node.js быстрее Java)

Частые ошибки

  • Создавать соединение с БД внутри handler — создаётся при каждом вызове; нужно выносить за пределы handler
  • Не ограничивать timeout — по умолчанию 3с, может быть мало; по умолчанию memory 128MB может быть мало для Node.js
  • Хранить большие зависимости в zip — Lambda слой (Layer) для общих зависимостей
  • Игнорировать холодный старт для latency-sensitive API

Связанные темы

Ресурсы