Highload на Go: System Design, Kubernetes и микросервисы под нагрузкой

Спроектируете Go-сервис, который в час пик отказывает лишним запросам за микросекунды, а остальным отвечает вовремя, и защитите каждое решение цифрами на system design интервью. Обычно сервис проверяют на ровном трафике, а ломается он под пиком: p99 уходит за таймаут клиента, мёртвая зависимость съедает горутины. Ставить ничего не нужно: брокер Kafka поднимается прямо в задании, манифесты применяются в настоящем кластере Kubernetes.

Чему вы научитесь

Какие запросы обслуживать, если мощности на всех не хватает?

Пул на 17 соединений, запрос к зависимости 20 мс: сервис тянет около 850 RPS. Поток в 1 200 RPS на 15 секунд это на 29% больше. Одна пятая потока приходится на checkout, остальное на рекомендации, клиент ждёт не дольше 2 с.

Три ответа сервиса в нашем прогоне. Очередь без лимита: с пятой секунды ни один ответ не укладывается в 2 с, вовремя получили 28% запросов. Отказ без разбора: 63% у checkout и 65% у рекомендаций. Резерв слотов под checkout: 99,4% у checkout, а ценой становятся 53% у рекомендаций.

В курсе вы строите эти механизмы сами: переборку на зависимость, ограниченную очередь, сброс нагрузки на входе и планировщик деградации по приоритету. Что отключать первым, решаете вы, а проверка смотрит, что критичный путь остался.

Что получает клиент, когда зависимость лежит

Зависимость молчит 10 секунд при 500 RPS, ответ в норме 20 мс, таймаут клиента 2 с. Без предохранителя все 5 000 запросов аварии получают ошибку, каждый после ожидания в 2 с, а в ожидании висит около тысячи горутин.

Предохранитель после пяти ошибок подряд отказывает сразу, за доли микросекунды. Но первые две секунды он не помогает: ошибки приходят только после таймаута, и пик в 1 002 горутины тот же. Затем ожидающих остаётся 0 или 1.

Цена другая. Зависимость ожила на 15-й секунде, а цепь закрылась на 17,08-й: 1 038 запросов получили отказ, хотя могли получить ответ. Автомат CLOSED, OPEN, HALF_OPEN вы пишете руками по тикам и считаете время в каждом состоянии по журналу переходов, поэтому видите цену каждого параметра.

Сквозной проект: лимитер, который переживает отказ Redis

Пик 13 890 RPS и 123 МБ состояния посчитаны в начале проекта. Подов несколько, поэтому счётчики лежат в Redis, а проверка и списание токена делает один Lua-скрипт: без него две реплики прочитают tokens=1 и обе пропустят запрос.

Когда Redis недоступен, лимитер не ждёт таймаут на каждом запросе: предохранитель отсекает вызовы, а каждый под считает по локальному token bucket. Лимит становится приблизительным, защита остаётся. Для платных квот выбрали бы fail-closed: решает то, что именно защищает лимитер.

Большая часть практики идёт в программах на Go и bash, которые моделируют механизм: token bucket, консистентное хеширование, такт HPA, разбор access-лога до p95. Очереди проходят на настоящем брокере Apache Kafka, а в Go-лабораторных код компилируется и запускается по-настоящему.

Для кого

Go-разработчикам, которые пишут фичи и хотят отвечать за поведение сервиса под пиком: очереди, таймауты, реплики, отказы зависимостей.

Тем, кто готовится к system design интервью: метод ответа, оценки на салфетке, разборы типовых задач и капстоун как готовый рассказ.

Бэкендерам с другим основным языком, которые могут написать небольшую программу на Go: практика здесь на Go и bash.

Шесть реплик посчитаны верно. Что в расчёте упущено

Четыре пода на 91% от requests при цели 70% дают ceil(5,2) = 6 реплик. Формула верна, вывод неполон: новая реплика заработает примерно через 65 секунд после всплеска, а всплеск в 30 секунд закончится раньше. От него защищает запас в цели, а не автоскейлер.

Остальные замечания: откуда взяты requests, ведь утилизация считается от них, и что будет при снижении, где окно scaleDown по умолчанию 300 секунд.

Манифесты вы пишете сами: requests и limits под нужный QoS-класс, HPA по двум метрикам, behavior для scaleDown. Проверка применяет их в настоящем кластере и читает результат через kubectl get, включая QoS-класс, который вычислил Kubernetes.

Что нужно знать

Go на уровне своей небольшой программы: package main, срезы, map, структуры, чтение stdin. Решения пишутся как полные программы на стандартной библиотеке.

Горутины и каналы хотя бы на уровне синтаксиса. Worker pool, context и select подробно разбираются в модуле про конкурентность.

Терминал и bash: решения по очередям пишутся в solution.sh, часть задач по логам решается через awk и sort.

Опыт с Kafka и Kubernetes не обязателен: перед лабораторными идёт теория, а подсказки в заданиях называют нужные флаги и поля манифеста.

Поддержка

Вы также можете задать любой вопрос по курсу у поддержки t.me/mentorix_support

Программа курса

Модулей: 13, уроков: 65. Задачи с кодом проверяются автоматически.

  1. Введение в highload: нагрузка, метрики, SLO

  2. Профилирование и оптимизация Go

  3. Кэширование под нагрузкой

  4. Rate limiting и балансировка нагрузки

  5. Устойчивость: таймауты, ретраи, circuit breaker

  6. Очереди и асинхронная обработка

  7. Базы данных под нагрузкой

  8. Микросервисы и API под нагрузкой

  9. Go-конкурентность под нагрузкой

  10. Наблюдаемость: метрики, логи, трейсы

  11. System Design: метод и разбор задач

  12. Kubernetes под нагрузкой

  13. Капстоун: highload-система от начала до конца

Стоимость курса: 19990 ₽

Открыть курс на Mentorix · Все курсы