Введение в Serverless и AWS Lambda на C#
Serverless-архитектура (бессерверные вычисления) — это модель разработки, при которой разработчик сосредотачивается исключительно на коде бизнес-логики, а инфраструктурой (серверами, масштабированием, мониторингом) управляет облачный провайдер. AWS Lambda — один из самых популярных сервисов для реализации serverless-функций, и он отлично поддерживает экосистему .NET.
В этой статье мы разберем полный цикл работы с AWS Lambda на C#: от создания проекта до деплоя и отладки. Вы узнаете, как настроить среду, написать эффективную функцию, обрабатывать события и избежать типичных ошибок. Материал ориентирован на разработчиков C#, которые хотят освоить serverless-подход в Amazon Web Services.
1. Настройка окружения и создание первого проекта
Установка инструментов
Для работы с AWS Lambda на C# вам понадобятся:
- .NET SDK версии 6.0 или 8.0 (рекомендуется последняя LTS-версия).
- AWS CLI — интерфейс командной строки для управления сервисами AWS.
- Amazon.Lambda.Templates — набор шаблонов для .NET CLI.
- Docker Desktop (опционально) — для локального тестирования с эмуляцией Lambda.
Установите шаблоны Lambda через терминал:
dotnet new -i Amazon.Lambda.Templates
Создание проекта
Создайте новую Lambda-функцию с помощью команды:
dotnet new lambda.EmptyFunction -n MyFirstLambda -o ./MyFirstLambda
cd MyFirstLambda
Структура проекта включает файл Function.cs с базовым классом Function и методом-обработчиком. По умолчанию используется шаблон для простой функции, принимающей строку и возвращающей строку.
Откройте Function.cs и измените его следующим образом:
using Amazon.Lambda.Core;
using Amazon.Lambda.Serialization.SystemTextJson;
[assembly: LambdaSerializer(typeof(DefaultLambdaJsonSerializer))]
public class Function
{
public string FunctionHandler(string input, ILambdaContext context)
{
context.Logger.LogInformation($"Получен ввод: {input}");
return $"Привет, {input}! Ваша функция выполнена успешно.";
}
}
Локальное тестирование
Для запуска функции локально используйте утилиту dotnet lambda invoke или эмулятор Lambda Runtime Interface Emulator (RIE) в Docker. Пример с RIE:
docker run --rm -v "$PWD/bin/Release/net8.0/publish":/var/task:ro,delegated \
-p 9000:8080 \
public.ecr.aws/lambda/dotnet8:latest \
MyFirstLambda::MyFirstLambda.Function::FunctionHandler
Отправьте тестовый запрос через curl:
curl -X POST "http://localhost:9000/2015-03-31/functions/function/invocations" \
-d '"Мир"'
2. Обработка различных типов событий
Работа с API Gateway (HTTP-запросы)
Чаще всего Lambda используется как бэкенд для REST API через Amazon API Gateway. В этом случае обработчик принимает объект APIGatewayProxyRequest и возвращает APIGatewayProxyResponse.
Установите NuGet-пакет:
dotnet add package Amazon.Lambda.APIGatewayEvents
Пример функции-обработчика HTTP POST запроса:
using Amazon.Lambda.APIGatewayEvents;
using System.Text.Json;
public class Function
{
public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
{
context.Logger.LogInformation($"Получен запрос: {request.HttpMethod} {request.Path}");
// Парсинг тела запроса
var body = JsonSerializer.Deserialize<Dictionary<string, string>>(request.Body);
var name = body?.GetValueOrDefault("name") ?? "Гость";
// Формирование ответа
var response = new APIGatewayProxyResponse
{
StatusCode = 200,
Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } },
Body = JsonSerializer.Serialize(new { message = $"Привет, {name}!" })
};
return response;
}
}
Обработка S3-событий
Lambda может автоматически запускаться при загрузке файла в S3-бакет. Для этого используется пакет Amazon.Lambda.S3Events.
using Amazon.Lambda.S3Events;
using Amazon.S3;
using Amazon.S3.Model;
public class Function
{
private readonly IAmazonS3 _s3Client;
public Function()
{
_s3Client = new AmazonS3Client();
}
public async Task FunctionHandler(S3Event evnt, ILambdaContext context)
{
foreach (var record in evnt.Records)
{
var bucketName = record.S3.Bucket.Name;
var objectKey = record.S3.Object.Key;
context.Logger.LogInformation($"Новый файл: {objectKey} в бакете {bucketName}");
// Чтение содержимого файла
var response = await _s3Client.GetObjectAsync(bucketName, objectKey);
using var reader = new StreamReader(response.ResponseStream);
var content = await reader.ReadToEndAsync();
// Логика обработки файла
await ProcessFile(content);
}
}
private Task ProcessFile(string content)
{
// Ваша бизнес-логика
return Task.CompletedTask;
}
}
3. Работа с конфигурацией и секретами
В serverless-приложениях важно не хранить чувствительные данные в коде. AWS Lambda предоставляет два основных механизма для работы с конфигурацией:
- Переменные окружения — задаются при создании или обновлении функции.
- AWS Systems Manager Parameter Store — сервис для хранения параметров и секретов.
Чтение переменных окружения
Доступ к переменным осуществляется через стандартный механизм .NET:
public class Function
{
private readonly string _connectionString;
public Function()
{
_connectionString = Environment.GetEnvironmentVariable("DB_CONNECTION_STRING")
?? throw new InvalidOperationException("Переменная DB_CONNECTION_STRING не задана");
}
public string FunctionHandler(string input, ILambdaContext context)
{
// Используем _connectionString
return $"Строка подключения: {_connectionString}";
}
}
Использование Parameter Store
Для получения параметров из AWS Systems