Как понять, что клиентский запрос прошел через все сервисы
Что проверяют
Понимаете ли вы, как в распределённой системе проследить один конкретный запрос, и умеете ли пользоваться этим как тестировщик, а не только читать отчёт разработчиков. Следом часто спрашивают, что делать, если часть цепочки идёт асинхронно через очередь.
Как отвечать
Основа ответа это сквозной идентификатор запроса:
- trace id: на входе в систему, обычно на API-шлюзе, запросу присваивается идентификатор, и каждый сервис передаёт его дальше. Стандартный заголовок для этого
traceparentиз спецификации W3C Trace Context, её поддерживает OpenTelemetry; - распределённая трассировка: Jaeger, Zipkin или Grafana Tempo показывают дерево спанов по одному trace id. Видно, какие сервисы участвовали, сколько занял каждый шаг и где цепочка оборвалась;
- логи: если трассировки нет, ищите по correlation id в Kibana или Loki. Для этого сервисы должны писать идентификатор в каждую строку лога, и это само по себе стоит проверить;
- асинхронные участки: в Kafka или RabbitMQ идентификатор едет в заголовках сообщения. Проверьте, что консьюмер его подхватывает, иначе след обрывается на очереди;
- итоговое состояние: трассировка показывает, что сервис вызвали, но не то, что он отработал правильно. Поэтому смотрите и данные: запись в базе заказов, событие в топике, статус в API соседнего сервиса.
В автотестах удобно самим задать уникальный идентификатор в запросе и потом собрать по нему события из логов или API трассировки. Так проверка становится воспроизводимой.
Где спотыкаются
Называют Prometheus и дашборды Grafana способом проследить запрос. Метрики агрегированы: они покажут рост ошибок, но не путь одного запроса.
Проверяют только ответ клиенту. Код 200 может вернуться до того, как асинхронная часть отработала или упала.
Не учитывают сэмплирование. Трассировка часто сохраняет только часть запросов, и отсутствие трейса ещё не значит, что запрос не дошёл.