Масштабирование и надёжность

Обновлено 5 мин чтения

Observability: почему мало знать, что система сломалась

Зависший документ, зелёные серверы и несколько команд, у каждой из которых всё работает. Какие данные помогут восстановить картину и выбрать действие.

Клиент загрузил документ и ждёт результат проверки. Поддержка видит, что файл принят. Команда API показывает успешный ответ, обработчики — отсутствие ошибок, инфраструктура — свободные ресурсы. Только готового документа нет. В этот момент компании нужен ответ на довольно простой вопрос: на каком шаге остановилась работа и кого ещё это затронуло?

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

Сначала разберёмся, что считается выполненной работой

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

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

Отдельно стоит определить допустимые исходы. Документ может быть корректно отклонён по понятной причине. Это отличается от технической ошибки обработки, но оба результата нужно довести до пользователя. Исчезнувшая задача не должна выглядеть как отсутствие проблем только потому, что никто не записал ошибку.

Три вида данных помогают ответить на разные вопросы

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

Журналы дают подробности отдельных событий: этап начался, проверка завершилась, внешняя система отказала. Они становятся заметно полезнее, когда поля имеют устойчивые названия и события можно связать с одной операцией. Строка «ошибка обработки» без контекста обычно требует нового разговора с её автором.

Трассировка связывает измеренные шаги между компонентами. Она помогает увидеть, где конкретный запрос ждал, но не заменяет сводный показатель качества. Один сохранённый неудачный случай ещё не показывает, скольких пользователей затронул инцидент.

Это не три обязательные закупки. Для небольшого приложения нескольких хороших метрик и связанных журналов может хватить. И противопоставление «мониторинг замечает, observability объясняет» слишком жёсткое: обычный мониторинг тоже помогает искать причины. Вопрос в том, какие выводы позволяют сделать имеющиеся данные, а не как назван инструмент.

Между сигналами нужен общий контекст

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

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

В межсервисной системе передача контекста должна работать и через очередь. Иначе история оборвётся как раз там, где клиент перестал ждать синхронный ответ. Связь сигналов и границы доверия при такой передаче описаны в документации OpenTelemetry.

Не каждый график должен будить дежурного

Уведомление имеет смысл, когда требует действия. Массовое увеличение времени подготовки документов может требовать немедленной реакции. Постепенный рост расхода хранилища — плановой задачи. Отдельный технический всплеск без последствий иногда достаточно сохранить для расследования.

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

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

За подробности приходится платить и деньгами, и доступом к данным

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

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

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

Приёмка на одном обращении клиента

Хорошее первое упражнение — выбрать зависший тестовый документ и попросить дежурного, который не писал обработчик, найти его судьбу. Где работа остановилась? Какой круг пользователей затронут? Что известно наверняка, а что пока предположение? Как проверить, помогло ли вмешательство?

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