Serverless функции на C++: AWS Lambda — полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Почему C++ в Serverless?

Мир serverless-вычислений прочно ассоциируется с JavaScript (Node.js), Python или Java. Однако для задач, критичных к производительности и потреблению памяти, C++ становится идеальным кандидатом. AWS Lambda поддерживает C++ через Native Runtime, позволяя запускать бинарные файлы с минимальными накладными расходами.

В этой статье мы разберём, как написать, скомпилировать и развернуть C++ функцию на AWS Lambda. Вы узнаете о преимуществах C++ в serverless-архитектуре, настройке окружения и оптимизации холодного старта.

1. Преимущества C++ перед Python и Node.js

Производительность и холодный старт

Главный недостаток интерпретируемых языков — задержка при холодном старте. Lambda-контейнер с Python может инициализироваться 200-500 мс, а с C++ — менее 50 мс. Это критично для API с высокими требованиями к latency.

  • Низкое потребление памяти: C++ бинарник занимает ~1-3 МБ против 20+ МБ для Node.js с зависимостями.
  • Прямой доступ к системным ресурсам: Работа с сокетами, файлами и памятью без прослойки VM.
  • Экономия: За счёт быстрого выполнения вы платите меньше за миллисекунды работы.

2. Настройка окружения для C++ на AWS Lambda

Для компиляции C++ кода под Lambda необходимо использовать Amazon Linux 2 (или совместимый образ). Рекомендуемый способ — Docker-контейнер с официальным образом Lambda.

Требования

  • CMake ≥ 3.15
  • GCC 7.3+ или Clang 7+
  • AWS SDK for C++ (опционально, для работы с S3/DynamoDB)
  • Docker (для сборки в среде, идентичной Lambda)

Базовый Dockerfile для сборки

FROM public.ecr.aws/lambda/provided:al2

# Установка инструментов сборки
RUN yum install -y gcc-c++ cmake3 make

# Копируем исходники
COPY . /code
WORKDIR /code/build

# Сборка статического бинарника
RUN cmake3 .. -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_CXX_FLAGS="-static-libstdc++ -static-libgcc" \
    && make -j$(nproc)

# Копируем результат в директорию Lambda
RUN cp handler /var/task/bootstrap
CMD ["handler"]

3. Пишем Lambda-функцию на C++

В отличие от Python, где handler — это функция, в C++ мы создаём исполняемый файл, который Lambda запускает как процесс. Входные данные передаются через stdin, а результат выводится в stdout.

Простой пример: обработка JSON

#include <iostream>
#include <string>
#include <nlohmann/json.hpp>  // Библиотека для работы с JSON

using json = nlohmann::json;

int main() {
    // Читаем весь stdin (входной JSON от Lambda)
    std::string input;
    std::getline(std::cin, input);

    try {
        auto event = json::parse(input);

        // Извлекаем параметры
        std::string name = event.value("name", "World");
        int number = event.value("number", 0);

        // Формируем ответ
        json response = {
            {"message", "Hello, " + name + "!"},
            {"computed", number * 2},
            {"language", "C++"}
        };

        std::cout << response.dump() << std::endl;
        return 0;
    } catch (const std::exception& e) {
        std::cerr << "{\"error\":\"" << e.what() << "\"}" << std::endl;
        return 1;
    }
}

Структура CMakeLists.txt

cmake_minimum_required(VERSION 3.15)
project(lambda-handler)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Статическая линковка для портативности
set(CMAKE_EXE_LINKER_FLAGS "-static-libstdc++ -static-libgcc")

# Подключаем nlohmann/json (vcpkg или fetch)
find_package(nlohmann_json REQUIRED)

add_executable(handler main.cpp)
target_link_libraries(handler PRIVATE nlohmann_json::nlohmann_json)

4. Деплой и тестирование

Шаг 1: Сборка

Запустите Docker-контейнер для компиляции. После сборки бинарник handler будет лежать в /var/task/bootstrap.

docker build -t lambda-cpp .
docker cp $(docker create lambda-cpp):/var/task/bootstrap ./bootstrap
chmod +x bootstrap
zip function.zip bootstrap

Шаг 2: Создание Lambda-функции

  • В консоли AWS Lambda выберите Custom runtime (provided.al2).
  • Загрузите function.zip.
  • Установите таймаут 10 секунд (для надёжности).
  • Назначьте IAM-роль с нужными разрешениями.

Шаг 3: Тестирование

Создайте тестовое событие с JSON:

{
  "name": "Serverless C++",
  "number": 42
}

Ожидаемый ответ:

{
  "message": "Hello, Serverless C++!",
  "computed": 84,
  "language": "C++"
}

5. Оптимизация холодного старта

Чтобы C++ Lambda запускалась максимально быстро, следуйте этим рекомендациям:

  • Статическая линковка: Избегайте динамических библиотек (libstdc++.so.6 и т.д.).
  • Минимизация бинарника: Используйте strip для удаления отладочных символов.
  • Pre-warming: Настройте CloudWatch Events для периодического вызова функции (каждые 5 минут).
  • Используйте AWS Lambda Extensions: Для кэширования данных на диске /tmp.

Заключение

C++ — мощный инструмент для serverless-разработки, если вам нужна максимальная производительность и минимальные затраты.

Блоги

Рекомендаций по книгам