17 августа с 13:28 до 21:15 UTC GitHub пережил аварию продолжительностью 7 часов 47 минут. Как сказано в итоговом сообщении GitHub Status, на пике около 20% запросов к сайту и программному интерфейсу завершались ошибкой; для скачивания архивов и отдельных файлов показатель доходил примерно до 50%. Сбой затронул задачи Issues, запросы на слияние, Actions, Copilot, а также несколько способов корпоративной авторизации и синхронизации пользователей.

Это не была неудачная публикация новой версии. В последующем разборе GitHub компания отдельно указала, что аварию не запустило изменение кода или конфигурации. Трафик достиг нового пика, а важный элемент инфраструктуры в дата-центре Central US не увеличил мощность вместе с ним. Дальнейшее восстановление затянула уже не исходная нехватка, а попытки систем и клиентов получить ответ снова.

Автомасштабирование смотрело не на тот предел

Первым был исчерпан предел параллельной обработки сетевого прокси Istio — небольшого посредника, который работает рядом с основным сервисом и проводит его входящие и исходящие запросы. Сам сервис при этом мог выглядеть достаточно здоровым. Политика автомасштабирования наблюдала за показателями основного процесса, но не учитывала ограничение прокси, поэтому система не добавила экземпляры в тот момент, когда сетевой слой уже переставал справляться.

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

Эта последовательность важнее слова «масштабирование». Дополнительные серверы помогают только тогда, когда сигнал охватывает фактическое узкое место. Наблюдение за загрузкой основного процесса не заменяет отдельные показатели очередей, параллельной обработки в прокси Istio, числа потоков балансировщика и доли повторных запросов.

Повторный запрос стал новой причиной перегрузки

Во внутренних шлюзах GitHub действовала оптимистичная логика: если ответ задерживался или не приходил, запрос можно было повторить. При коротком случайном сбое такой подход скрывает проблему от пользователя. Когда зависимость уже работает на пределе, каждый повтор занимает ещё одно место в очереди и уменьшает шанс, что первый запрос вообще завершится.

Независимое издание The Register обратило внимание на вторую петлю: задержка одного внутреннего ответа обнаружила скрытую ошибку повторов в Visual Studio Code. Обычный поток к Copilot Token Service составлял 7–9 тысяч запросов в секунду, а во время восстановления вырос до 70–100 тысяч. GitHub описал усиление как приблизительно десятикратное.

Поэтому Copilot оставался повреждённым после того, как большая часть GitHub уже вернулась. Клиентская программа не создала исходный сетевой предел, но поддерживала нагрузку, когда сервису требовалось свободное место для восстановления. Одинаковая команда «попробовать ещё раз» была полезна в обычной сети и разрушительна в массовом отказе.

Восстановление пришлось разложить на этапы

Инженеры перенаправили часть трафика из Central US в Northern Virginia и одновременно изолировали перегруженные компоненты. Временная остановка HAProxy на четырёх исчерпавших лимиты узлах дала широкое восстановление. Но вернуть весь поток сразу было нельзя: старые повторы могли снова заполнить освобождённую ёмкость.

GitHub уменьшил число повторов на шлюзе отдельной правкой, а балансировщики начали отвечать кодом 403 на входящие запросы к сервису токенов Copilot. Это остановило петлю, после чего трафик возвращали постепенно по площадкам. Большинство сервисов восстановилось к 16:36 UTC, Actions оставался повреждённым примерно до 18:03, Copilot Token Service — до 21:02; весь инцидент закрыли в 21:15.

Распределённый Git сохраняет код, но не рабочий день

Распределённое устройство Git действительно смягчает часть аварии. В уже склонированном репозитории остаются файлы, история коммитов и локальные ветки. Разработчик может читать код, создавать коммиты, сравнивать изменения и собирать проект, если нужные зависимости и инструменты уже доступны.

Но GitHub давно обслуживает больше, чем удалённое хранилище Git. Запросы на слияние и их обсуждения, задачи Issues, сборки Actions, корпоративная авторизация, правила одобрения, токены Copilot, архивы и отдельные исходные файлы проходят через сервисы платформы. Локальный коммит не отправит изменение коллегам, не запустит размещённую сборку и не восстановит секрет, который выдаётся только рабочему процессу Actions.

Поэтому план непрерывности начинается не с обещания «у нас всё локально», а с карты зависимостей. Команда должна знать, можно ли собрать и проверить критическое исправление без GitHub, где лежат пакеты и артефакты выпуска, как связаться с проверяющими и какой удалённый путь разрешён во время продолжительного отказа. Резервная копия репозитория сохраняет интеллектуальную собственность; рабочую координацию приходится проектировать отдельно.

У повторов должен быть общий бюджет

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

  1. Задать общий бюджет повторов: максимальное число дополнительных запросов за интервал для всей цепочки, а не отдельный безобидный лимит в каждом сервисе.
  2. Увеличивать паузу между попытками и добавлять случайный разброс, чтобы тысячи клиентов не возвращались в одну миллисекунду.
  3. Размыкать цепь после устойчивой серии ошибок и возвращать понятный временный ответ, пока зависимость не восстановит запас.
  4. Наблюдать отдельно за параллельной обработкой в прокси Istio, лимитами сетевых потоков балансировщиков, длиной очереди, долей повторов и скоростью восстановления.
  5. Проверить автономный путь работы: локальную сборку, сохранность артефактов, порядок ручного выпуска и согласованный резервный канал координации.

Результатом такой работы должны быть не только настройки библиотек, но и воспроизводимый сценарий отказа, пределы нагрузки, сигналы тревоги и решение о том, какая функция временно отключается первой. В ходе восстановления GitHub сократил число повторов на шлюзе, начал отклонять часть запросов к Copilot Token Service кодом 403 и затем постепенно вернул трафик. Устойчивость здесь означает не умение всегда повторить запрос, а умение вовремя прекратить спрашивать.