Chaos Engineering для C#: ломаем приложения, чтобы спасти бизнес

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

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

Начать курс

Введение: Почему ваш C# сервис — это не идеальный механизм

Представьте: вы написали элегантный микросервис на C#. Код прошел code review, unit-тесты покрывают 95%, интеграционные тесты зеленые. Вы выкатываете его в прод, и… через 3 часа система падает. Причина? Неожиданный скачок трафика, который перегрузил пул потоков, или внезапное отключение базы данных, которое вы не предусмотрели.

Добро пожаловать в реальный мир, где Chaos Engineering (хаос-инжиниринг) становится не роскошью, а необходимостью. Это не про «сломать всё ради веселья». Это дисциплина, которая помогает выявлять слабые места в распределенных системах до того, как их обнаружат ваши пользователи.

В этой статье мы разберем, как применять Chaos Engineering для C# приложений: от теории до реальных примеров кода с использованием библиотек Polly и Simmy. Вы узнаете, как целенаправленно вносить хаос в .NET сервисы, чтобы повысить их устойчивость и предсказуемость.

Что такое Chaos Engineering и почему это важно для .NET?

Chaos Engineering — это практика проведения экспериментов над распределенной системой, чтобы проверить её способность выдерживать неожиданные сбои. Netflix, Amazon, Microsoft — все гиганты используют это. Для C# разработчиков это особенно актуально, так как .NET Core/5+ все чаще используется для построения высоконагруженных, облачных сервисов на Microsoft Azure.

Основные принципы хаос-инжиниринга:

  • Определение «steady state» (стабильного состояния) — как ваша система ведет себя в норме (латентность, throughput, error rate).
  • Формулировка гипотезы — «Если упадет база данных OrderDB, сервис заказов продолжит отвечать с кешированными данными в течение 5 минут».
  • Внесение хаоса — вы реально отключаете OrderDB на 30 секунд.
  • Проверка гипотезы — смотрим метрики. Если гипотеза не подтвердилась — у вас есть баг в архитектуре.

Ключевое слово здесь — «эксперимент». Вы не просто надеетесь на лучшее, вы доказываете, что ваша система выживет.

Инструментарий для Chaos Engineering в C#

В мире .NET существует два мощных инструмента, которые работают в связке:

  • Polly — библиотека для реализации паттернов отказоустойчивости (Retry, Circuit Breaker, Timeout, Bulkhead Isolation).
  • Simmy (Microsoft.Extensions.Resilience) — библиотека для хаос-инжиниринга, расширяющая Polly. Позволяет «инжектировать» сбои в ваши политики.

Simmy — это «злой брат» Polly. Если Polly учит ваше приложение выживать, то Simmy проверяет, насколько хорошо оно это умеет, целенаправленно ломая вызовы.

Практика: Настройка хаос-эксперимента на C#

Давайте перейдем к коду. Допустим, у нас есть сервис бронирования, который обращается к внешнему API оплаты. Мы хотим проверить, как поведет себя BookingService, если API оплаты начнет отвечать с задержкой или ошибками.

Шаг 1: Установка пакетов

dotnet add package Microsoft.Extensions.Http.Polly
dotnet add package Microsoft.Extensions.Resilience

Шаг 2: Настройка HttpClient с политиками

Сначала мы настраиваем стандартную политику Circuit Breaker и Retry с помощью Polly. Затем мы «оборачиваем» её в политику хаоса из Simmy.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Http.Resilience;
using Polly;
using Polly.Extensions.Http;

public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddPaymentClient(this IServiceCollection services)
    {
        services.AddHttpClient<IPaymentService, PaymentService>(client =>
        {
            client.BaseAddress = new Uri("https://api.payment-gateway.com");
            client.Timeout = TimeSpan.FromSeconds(5);
        })
        .AddPolicyHandler(GetChaosPolicy()); // Добавляем хаос

        return services;
    }

    private static IAsyncPolicy<HttpResponseMessage> GetChaosPolicy()
    {
        // 1. Базовая политика отказоустойчивости (Polly)
        var retryPolicy = HttpPolicyExtensions
            .HandleTransientHttpError()
            .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.InternalServerError)
            .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));

        var circuitBreakerPolicy = HttpPolicyExtensions
            .HandleTransientHttpError()
            .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));

        var basePolicy = Policy.WrapAsync(retryPolicy, circuitBreakerPolicy);

        // 2. Политика хаоса (Simmy)
        var chaosPolicy = new ChaosPolicyBuilder<HttpResponseMessage>()
            .For<HttpRequestException>(injectionRate: 0.1) // 10% запросов будут падать с исключением
            .ForResult(response => new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError), injectionRate: 0.05) // 5% запросов вернут 500
            .ForLatency(delay: TimeSpan.FromMilliseconds(500), injectionRate: 0.2) // 20% запросов будут замедлены на 500 мс
            .Build();

        // Оборачиваем: сначала хаос, потом защита
        return Policy.WrapAsync(chaosPolicy, basePolicy);
    }
}

Что здесь происходит?

  • ChaosPolicyBuilder позволяет задать injectionRate — процент запросов, которые будут подвержены хаосу.
  • Мы настроили три типа сбоев: исключение, HTTP 500 и задержка.
  • Политика хаоса обернута поверх политики отказоустойчивости. Это значит, что сначала Simmy «ломает» запрос, а потом Polly пытается его «спасти» (ретрей или размыкание цепи).

Шаг 3: Мониторинг и сбор метрик

Хаос без метрик — это просто разрушение. Используйте Application Insights или Prometheus + Grafana. Simmy автоматически записывает телеметрию, если вы подключили Microsoft.Extensions.Telemetry.

// В Program.cs добавьте:
builder.Services.AddOpenTelemetry()
    .WithMetrics(metrics => metrics
        .AddAspNetCoreInstrumentation()
        .AddHttpClientInstrumentation()
        .AddMeter("Polly")
        .AddMeter("Simmy"));

Вы увидите счетчики: chaos-policy.injections, chaos-policy.latency и т.д. Это позволит вам видеть, как часто происходят «сбои» и как на них реагирует система.

Сценарии хаос-экспериментов для C# приложений

Вот 3 реалистичных сценария, которые можно протестировать с помощью описанного подхода:

1. Тест на

Блоги

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