Serverless на C#: AWS Lambda, Azure Functions и будущее бессерверной разработки

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

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

Начать курс

Почему Serverless — это не просто хайп, а спасение для вашего кошелька и нервов

Представьте: вы написали крутой API на C#, запустили его на виртуальной машине, а он простаивает 23 часа в сутки. Вы платите за воздух. Знакомо? Если да, то serverless функции на C# — это ваш спасательный круг. Бессерверные вычисления (или Function-as-a-Service) позволяют вам выполнять код только тогда, когда он реально нужен. Никакой аренды серверов, никакой ручной настройки CI/CD для инфраструктуры, никакой головной боли с масштабированием.

В этой статье мы разберем, как писать serverless функции на C# для AWS Lambda и Azure Functions, сравним их, напишем реальный код и поймем, почему это лучший выбор для микросервисов, обработчиков событий и бэкенда для мобильных приложений. И да, здесь будет много кода — без воды.

AWS Lambda и C#: как подружить два мощных инструмента

AWS Lambda C# — это, пожалуй, самый популярный вариант для .NET-разработчиков, работающих с Amazon Web Services. Lambda поддерживает .NET Core 3.1, .NET 6, .NET 8 и даже .NET 9 (проверьте актуальность на момент чтения). Главное преимущество — вы пишете на привычном C#, а AWS сам заботится о рантайме.

Создаем первую Lambda-функцию на C#

Для начала установите AWS Toolkit для Visual Studio или используйте .NET CLI. Создадим проект с шаблоном «AWS Lambda Project».

dotnet new lambda.EmptyFunction --name HelloWorldFunction
cd HelloWorldFunction
dotnet add package Amazon.Lambda.Core
dotnet add package Amazon.Lambda.Serialization.SystemTextJson

Теперь напишем саму функцию. Классический пример — обработка запроса API Gateway и возврат JSON.

using Amazon.Lambda.Core;
using Amazon.Lambda.Serialization.SystemTextJson;

[assembly: LambdaSerializer(typeof(DefaultLambdaJsonSerializer))]

public class Function
{
    public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest input, ILambdaContext context)
    {
        var message = $"Привет, мир! Твой запрос: {input.Body ?? "пусто"}";
        context.Logger.LogInformation("Вызвана Lambda функция");

        return new APIGatewayProxyResponse
        {
            StatusCode = 200,
            Body = JsonSerializer.Serialize(new { message, timestamp = DateTime.UtcNow }),
            Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } }
        };
    }
}

Обратите внимание: код асинхронный, использует встроенную сериализацию JSON и логирование. Это минимально жизнеспособный продукт, который уже может работать под нагрузкой.

Почему AWS Lambda выигрывает для C#?

  • Cold start: AWS оптимизировал запуск .NET функций через SnapStart — теперь старт занимает менее 200 мс.
  • Интеграция: Из коробки работает с S3, DynamoDB, SQS, API Gateway.
  • Мониторинг: CloudWatch собирает логи, метрики, ошибки.

Azure Functions для C#: достойная альтернатива от Microsoft

Если ваш проект уже завязан на экосистему Microsoft (Azure DevOps, Active Directory, SQL Server), то Azure Functions C# может оказаться удобнее. Они поддерживают не только изолированный процесс (isolated process), но и внутрипроцессную модель.

Пример функции на C# для Azure

Создадим HTTP-триггер с помощью Azure Functions Core Tools:

func init MyFunctionApp --dotnet-isolated
cd MyFunctionApp
func new --name HttpExample --template "HTTP trigger"

Код функции:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

public class HttpExample
{
    private readonly ILogger<HttpExample> _logger;

    public HttpExample(ILogger<HttpExample> logger)
    {
        _logger = logger;
    }

    [Function("HttpExample")]
    public HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req)
    {
        _logger.LogInformation("C# HTTP trigger function processed a request.");

        var response = req.CreateResponse(HttpStatusCode.OK);
        response.Headers.Add("Content-Type", "application/json; charset=utf-8");
        response.WriteString(JsonSerializer.Serialize(new { result = "Привет из Azure Functions!" }));

        return response;
    }
}

Видите разницу? Azure использует конструктор для внедрения логгера, атрибуты для триггеров и отдельные классы для ответов. Это более «тяжелая» модель, но она дает больше контроля.

Сравнение AWS Lambda vs Azure Functions для C#

Давайте сведем ключевые параметры в таблицу:

ПараметрAWS LambdaAzure Functions
Холодный стартУлучшен SnapStartPremium-план ускоряет
ТриггерыS3, SQS, API GW, DynamoDBBlob, Queue, Event Grid, HTTP
ЦенообразованиеЗа 1 млн запросов ~$0.20Бесплатно 1 млн запросов/мес
Лучший сценарийСложная event-driven архитектураИнтеграция с Microsoft стеком

Выбор между serverless функциями на C# для AWS или Azure часто сводится не к технологиям, а к тому, где уже развернута ваша инфраструктура.

Альтернативы: Google Cloud Functions, Yandex Cloud и OpenFaaS

Не стоит забывать про другие облака. Google Cloud Functions тоже поддерживает C# (через .NET runtime), но популярность ниже. В России активно используют Yandex Cloud Functions — они дружат с .NET 6+ и имеют низкие цены для локального рынка.

Если вы хотите полный контроль, попробуйте OpenFaaS — open-source платформа для serverless. Вы разворачиваете ее на своем Kubernetes и пишете функции на C# в Docker-контейнерах. Это гибко, но требует DevOps-скиллов.

Лучшие практики написания C# serverless функций

Чтобы ваши функции не тормозили и не разоряли вас, запомните несколько правил:

  • Минимизируйте cold start: Используйте статические конструкторы для инициализации тяжелых объектов (например, DBContext).
  • Не храните состояние: Serverless — это stateless. Любые данные между вызовами храните в Redis, DynamoDB или Blob Storage.
  • Логируйте всё: Используйте ILogger или CloudWatch. Когда функция упадет в 3 ночи, логи — ваше спасение.
  • Ограничивайте таймауты: AWS Lambda имеет лимит 15 минут, Azure — 10 минут (по умолчанию). Не делайте функции долгими.
  • Используйте DI: И в AWS (через Lambda DI), и в

Блоги

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