Лабораторная 04: Система выдерживает проверку
Соберите сервис целиком, добавьте метрики и трассировку. Проведите нагрузочный эксперимент и сценарий отказа, защитите решения.
Код стенда, установка и шаблон отчёта
Лабораторная 4. Клиентский результат под нагрузкой и отказами
Проверьте сквозной проект, сохранив инварианты Lab1–3. Цель — измерить не только HTTP-ответ, но и завершение задачи, накопление очереди, ошибки и восстановление. Требуются исправленные предыдущие лабораторные и темы хвостовой задержки, наблюдаемости и эксплуатационных отказов. Ориентир — 90 минут плюс подготовка защиты.
Запуск
После подготовки по README, из корня репозитория:
PYTHONDONTWRITEBYTECODE=1 /tmp/ds-course-venv/bin/python labs/distributed-systems/runner.py --lab 4 --solution starter --report /tmp/lab04.json
PYTHONDONTWRITEBYTECODE=1 /tmp/ds-course-venv/bin/python labs/distributed-systems/runner.py --lab all --solution starter --report /tmp/project-final.json
Эталон запускается теми же командами с --solution reference. Нагрузочная программа и проверки находятся в tests/scenarios.py. Базовые counts — 24, 24 и 32 уникальные задачи, один последовательный клиент, намеренная пауза около 15 ms между первичными запросами. Это воспроизводимый малый опыт, не saturated throughput benchmark.
Задание
- До запуска запишите гипотезу отдельно для latency принятия и времени до завершения. Определите denominator: первичные запросы, все попытки с повторами, уникальные задачи.
- Сопоставьте JSON операции с JSONL API/relay/worker по task_id, event_id и trace_id. Найдите момент, в котором «HTTP успешно» ещё не означает «эффект завершён».
- Измените один параметр: скорость поступления, worker delay или timeout. Сохраните baseline и эксперимент; не меняйте одновременно все параметры. Объясните цену: очередь, доля ошибок, ожидание клиента, повторная работа.
- Подготовьте архитектурную защиту: атомарность, чтения, retry/retention, capacity assumptions, восстановление и внешний эффект вне границы.
Три сценария
- Медленный worker. Worker задерживает обработку на 120 ms, а клиент предлагает 24 задачи. Очередь должна действительно накопиться, затем опустеть. Измеряйте admission latency отдельно от completion и backlog drain.
- Брокер остановлен. Контейнер NATS останавливается, HTTP продолжает принимать 24 задачи в etcd. Pending outbox растёт. После возвращения того же broker volume все задачи должны завершиться без потери и повторного эффекта.
- Лидер меняется под нагрузкой. Во время потока 32 задач останавливается настоящий лидер etcd. Ошибки/неопределённые исходы повторяются с исходными ключами. После обработки и возврата третьего member сверяются все идентичности, results и counter.
Итоговый инвариант базового набора: 80 уникальных задач amount=1 дают 80 результатов и counter {effects:80,value:80} после восстановления, независимо от числа попыток и доставок. Ошибки во время отказа допустимы, но не должны скрываться из отчёта. Ноль наблюдённых ошибок в коротком прогоне не доказывает непрерывную доступность.
Что сдавать
- Машинный отчёт всех четырёх наборов, baseline и один изменённый опыт. Прилагайте команду, версии, ресурсы, counts и окно наблюдения.
- p50/p95/p99 HTTP admission с числом образцов и ошибками; отдельно completion latency, backlog и определённые интервалы восстановления. Укажите метод процентилей и погрешность polling.
- График backlog или таблицу нескольких снимков, причинную цепочку одного запроса и объяснение наиболее длинной задержки. Для всего trace нет единого синхронизированного wall clock: длительности измеряются monotonic clock runner.
- Отчёт, ADR, diff и инструкция повторения. Предлагаемые критерии защиты: корректность, воспроизводимость, измерения и честные ограничения; официальную шкалу устанавливает преподаватель.
Чтение и защита
The Tail at Scale помогает обсуждать хвосты и цену повторов; Simple Testing Can Prevent Most Critical Failures — прицельные отказы; MapReduce — повтор выполнения и медленные задачи. Поддерживающие исследовательские деки: Tail at Scale, Simple Testing, MapReduce и Kafka. Для определения пользовательского результата прочитайте SRE Workbook: Implementing SLOs.
На защите объясните, почему быстрый 201 совместим с медленным завершением, почему p99 по 24 точкам не надёжен для production, где возникает retry amplification, и что потребует новый протокол при внешнем платеже. Предложите альтернативу общей counter-записи, указав изменившийся инвариант и необходимость новых проверок.
Восстановление и границы
Runner очищает только собственный проект; параметры ручного cleanup после SIGKILL сохраняются рядом с отчётом, см. README. Один физический host, один брокер, короткий локальный прогон, сохранные диски и bounded payload — часть модели. Не переносите цифры на WAN или другой hardware. Различайте время наблюдения лидера, клиентскую доступность и восстановление избыточности; они не взаимозаменяемы.
В базовом ThreadingHTTPServer нет прикладного лимита конкурентных HTTP-запросов. Здесь исследуется очередь работы при ограниченном профиле нагрузки, не устойчивость сервера к неограниченной HTTP-перегрузке. Требования сквозного проекта и предложенные веса защиты: проект.
Предлагаемые критерии защиты
Это предложение автора, не регламент ВШЭ. Корректность — 40%: все обязательные инварианты четырёх наборов; воспроизводимость — 25%: команды, версии, реальные отказы и собственный cleanup; измерения — 20%: counts/errors, admission/completion, backlog и определённые интервалы; аргументация — 15%: два ADR, границы и обоснованная альтернатива. Полный уровень требует проверенного результата; частичный — честно обозначенного конкретного пробела; нулевой — отсутствия доказательства или подмены результата. Потерянный или повторный эффект не позволяет считать проект технически завершённым. Порог зачёта и точные баллы объявляет преподаватель. Полная рубрика с уровнями.