Serverless функции на C#: Полное руководство по AWS Lambda с .NET
Serverless-архитектура становится стандартом для современных приложений. AWS Lambda — один из самых популярных сервисов для выполнения кода без управления серверами. В этой статье мы разберем, как создавать serverless функции на C# с использованием .NET 6/8, настроить окружение, написать эффективный код и развернуть его в облаке.
Что такое AWS Lambda и почему C#?
AWS Lambda — это вычислительный сервис, который запускает ваш код в ответ на события и автоматически управляет вычислительными ресурсами. C# с .NET — отличный выбор для Lambda благодаря:
- Высокой производительности — .NET 6+ обеспечивает быстрый холодный старт (около 200-500 мс).
- Знакомому синтаксису — если вы уже пишете на C#, порог входа минимален.
- Богатой экосистеме — доступны все библиотеки NuGet.
- Интеграции с AWS — SDK для .NET позволяет легко работать с S3, DynamoDB, SQS и другими сервисами.
Serverless функции на C# идеально подходят для обработки файлов, REST API (через API Gateway), ETL-процессов и микросервисов.
Настройка проекта для AWS Lambda на C#
Для начала работы вам понадобится:
- .NET SDK 6.0 или выше
- Учетная запись AWS
- AWS CLI (рекомендуется)
- Инструмент
dotnet lambda(устанавливается черезdotnet tool install -g Amazon.Lambda.Tools)
Создадим новый проект:
dotnet new lambda.EmptyFunction --name MyFirstLambda
cd MyFirstLambda
Структура проекта включает:
Function.cs— основной файл с логикой.aws-lambda-tools-defaults.json— настройки деплоя.MyFirstLambda.csproj— файл проекта с необходимыми пакетами.
Убедитесь, что в .csproj есть ссылки на пакеты:
<PackageReference Include="Amazon.Lambda.Core" Version="2.2.0" />
<PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.3.1" />
Написание первой serverless функции на C#
Откроем Function.cs и напишем простой обработчик, который принимает имя и возвращает приветствие:
using Amazon.Lambda.Core;
using Amazon.Lambda.Serialization.SystemTextJson;
[assembly: LambdaSerializer(typeof(DefaultLambdaJsonSerializer))]
public class Function
{
public string FunctionHandler(Input input, ILambdaContext context)
{
context.Logger.LogInformation($"Обработка запроса для: {input.Name}");
return $"Привет, {input.Name}! Время: {DateTime.UtcNow}";
}
}
public class Input
{
public string Name { get; set; }
}
Разберем ключевые моменты:
LambdaSerializer— указывает, как сериализовать/десериализовать JSON.SystemTextJson— быстрый и современный вариант.ILambdaContext— предоставляет информацию о текущем вызове: остаток времени, логгер, ID запроса.Input— простой POCO-класс для входных данных.
Для тестирования локально используйте:
dotnet lambda invoke-function MyFirstLambda --payload "{\"Name\": \"Мир\"}"
Работа с AWS сервисами из Lambda
Реальная сила serverless функций на C# проявляется при интеграции с другими сервисами. Рассмотрим пример загрузки файла в S3:
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.Lambda.Core;
public class S3Function
{
private readonly IAmazonS3 _s3Client;
public S3Function()
{
_s3Client = new AmazonS3Client(); // использует IAM роль Lambda
}
public async Task<string> FunctionHandler(S3Event evnt, ILambdaContext context)
{
var bucketName = evnt.Records[0].S3.Bucket.Name;
var objectKey = evnt.Records[0].S3.Object.Key;
var response = await _s3Client.GetObjectAsync(bucketName, objectKey);
using var reader = new StreamReader(response.ResponseStream);
var content = await reader.ReadToEndAsync();
context.Logger.LogInformation($"Файл {objectKey} прочитан. Размер: {content.Length} символов");
return $"Processed {objectKey}";
}
}
Важные моменты для production:
- Повторное использование клиентов — создавайте
AmazonS3Clientв конструкторе, а не внутри обработчика. Это ускоряет работу за счет пула соединений. - Async/await — всегда используйте асинхронные методы для I/O операций.
- IAM роли — настройте минимальные права (например, только
s3:GetObjectдля конкретного бакета).
Оптимизация производительности
Serverless функции на C# требуют особого подхода к оптимизации:
1. Холодный старт
Первое выполнение после простоя занимает больше времени. Решения:
- Используйте
Provisioned Concurrency— держит заданное число экземпляров "горячими". - Минимизируйте зависимости в
.csproj— чем меньше DLL, тем быстрее загрузка. - Настройте
ReadyToRun(AOT-компиляция) для .NET 8:
<PropertyGroup>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
2. Размер пакета
Lambda имеет лимит в 50 МБ (сжатый) / 250 МБ (распакованный). Используйте:
dotnet lambda package— создает ZIP с оптимизированными сборками.- Удалите лишние файлы из папки
publish. - Рассмотрите использование Native AOT для .NET 8 — это дает минимальный размер.
3. Логирование и мониторинг
Блоги
Рекомендаций по книгам
Читайте также
Конкурентность и многопоточность в Swift: полное руководство