hw-07-08-distributed-patterns-Dremotha

0

Описание

Языки

  • Python21,8%
  • Rust21,2%
  • Go20,9%
  • C++18,1%
  • Dockerfile12,7%
  • CMake5,3%
4 месяца назад
4 месяца назад
4 месяца назад
4 месяца назад
4 месяца назад
4 месяца назад
4 месяца назад
4 месяца назад
4 месяца назад
4 месяца назад
Readme.md

Домашнее задание №7: Паттерны отказоустойчивости (Resilience)

Тема: Паттерны распределенных систем и Observability.
Цель: Сделать gRPC-клиент надежным в условиях нестабильной сети и сбоев сервера.


Архитектура и Легенда

У нас есть система из двух сервисов:

  1. Unstable Server (Сервер): Имитирует нестабильную работу (Payment Gateway, Legacy System).
    • В режиме
      CHAOS_MODE=true
      он периодически зависает на 5 секунд или возвращает ошибки.
  2. Resilient Client (Клиент): Ваш сервис, который должен обращаться к серверу.

Проблема: Текущая реализация клиента (или стандартная библиотека gRPC) не готова к сбоям. При зависании сервера клиент вечно ждет ответа, блокируя потоки, или падает при первой же ошибке.

Ваша задача: Реализовать на стороне клиента паттерны Timeout, Retry (с Exponential Backoff) и Circuit Breaker.


Как начать

Выберите язык реализации

Проект содержит заготовки для четырех языков. Выберите один, на котором будете выполнять задание.

  • Python:
    python/
    (Рекомендуется для быстрого старта). Использует
    uv
    .
  • Go:
    go/
    . Использует стандартный тулчейн Go.
  • C++:
    cpp/
    . Использует фреймворк userver и CMake.
  • Rust:
    rust/
    . Использует Tonic и Cargo.

Настройка окружения

Python (uv)

Если вы выбрали Python, убедитесь, что установлен uv.

Docker Compose

Для запуска всей системы (клиент + сервер + мониторинг) используется Docker.

По умолчанию в

docker-compose.yml
включен Python-сервер и Python-клиент. Если вы пишете на другом языке, отредактируйте секцию
services.client
в файле
docker-compose.yml
.


Задания

Часть 1: Реализация Паттернов (Обязательно)

Вам необходимо отредактировать файл клиента (например,

python/src/client.py
или конфиг
cpp/configs/config.yaml
) и внедрить следующие механики:

  1. Timeout (Таймаут):

    • Установите жесткий лимит ожидания ответа от сервера (2 секунды).
    • Проверка: Сервер в хаос-режиме иногда спит 5 секунд. Клиент не должен ждать, а должен падать с ошибкой
      DeadlineExceeded
      через 2 секунды.
  2. Retry (Повторные попытки):

    • Если получена ошибка сети или
      UNAVAILABLE
      , повторите запрос.
    • Используйте Exponential Backoff: задержка между попытками должна расти (например, 1с -> 2с -> 4с).
    • Ограничьте количество попыток (например, 3 раза).
  3. Circuit Breaker (Предохранитель):

    • Если сервер вернул ошибку 5 раз подряд, клиент должен перейти в состояние
      Open
      .
    • В этом состоянии запросы не отправляются в сеть, а сразу возвращается ошибка.
    • Через 30 секунд (Recovery Timeout) клиент должен попробовать сделать один запрос (
      Half-Open
      ).

Часть 2: Observability (Дополнительное задание)

  1. Запустите Prometheus и Grafana (раскомментируйте их в
    docker-compose.yml
    ).
  2. Настройте экспорт метрик из вашего клиента.
  3. Постройте дашборд в Grafana, показывающий:
    • RPS (Requests Per Second).
    • Количество ошибок.
    • Состояние Circuit Breaker (Closed/Open).

Подсказки по языкам

Python

  • Используйте декораторы
    @retry
    из библиотеки
    tenacity
    .
  • Используйте
    @circuit
    из библиотеки
    circuitbreaker
    .
  • Не забудьте сгенерировать proto-код:
    cd python && uv run python src/codegen.py
    .

Go

  • Используйте библиотеку
    gobreaker
    для Circuit Breaker.
  • Retry лучше реализовать явным циклом
    for
    для понимания работы Backoff.

C++ (userver)

  • Вам не нужно писать код C++. Вам нужно правильно настроить
    cpp/configs/config.yaml
    .
  • Найдите в документации userver параметры
    qos
    (attempts, timeout) и
    congestion-control
    .

Rust

  • В папке
    proto
    лежит общий контракт.
    build.rs
    автоматически скомпилирует его.
  • Для Retry и Timeout можно использовать крейт
    tower
    (Middleware) или реализовать логику вручную в
    client.rs
    .

Критерии приемки

  1. Pull Request с реализованным кодом.
  2. В README вашего форка приложены скриншоты логов, где видно:
    • Как клиент делает 3 попытки перед тем, как сдаться (Retry).
    • Как клиент перестает слать запросы после серии неудач (Circuit Breaker).
    • (Бонус) Скриншот дашборда Grafana.