Понимание OpenTelemetry и распределенной трассировки

Запуск распределенных систем в производство - непростая задача. Доступ ограничен, поэтому проблемы трудно отследить и понять, а также воспроизвести в других средах. Никакая другая среда не похожа на производственную, какой бы похожей она ни казалась. Обычно вы полагаетесь на разную информацию для устранения неполадок и понимания того, что происходит с вашими приложениями в производственной среде. Наиболее распространены журналы и специальные показатели. Эти две вещи действительно эффективны, если их объединить и использовать вместе. С помощью журналов вы можете понять и устранить именно то, что произошло с конкретным запросом или сценарием, а с помощью метрик вы можете увидеть общее поведение и производительность системы. Это похоже на действительно хорошее решение, и это действительно так, проблема в том, чтобы настроить его так, чтобы оно отражало именно то, что вам нужно. Вот несколько проблем, которые я вижу при реализации наблюдаемости и мониторинга в распределенных системах:

  • Корреляция журналов с показателями. В зависимости от платформы, которую вы используете для хранения данных, корреляция может быть очень сложной или очень ручной, особенно если вы используете одну платформу для журналов, а другую - для показателей. К сожалению, очень часто приходится вручную сопоставлять данные по меткам времени.
  • Сопоставление журналов и показателей из разных систем. Если вы не будете осторожны при реализации журналов в разных приложениях, информация, которую вы экспортируете в журналы, может отличаться, в случае структурированного ведения журнала может быть другой шаблон (или даже формат). Это означает, что запросы и попытки сопоставить вещи могут стать очень сложными. Не говоря уже о том, реализованы ли системы в разных технологиях, а поддержка журналов и метрик отличается.
  • Собственная логика поставщика (привязка). Одна большая проблема заключается в том, что каждый поставщик (платформа, серверные системы), с которым вы храните свои данные, может иметь другой протокол или набор библиотек для взаимодействия. Это может вызвать привязку к поставщику, когда вы не можете переключиться на другого поставщика из-за бремени и затрат на рефакторинг в вашей собственной базе кода, чтобы заменить всю необходимую логику для взаимодействия с их решением.

Эти моменты обычно нелегко решить и являются настоящей проблемой для тех, кто работает с распределенными системами в производственной среде. OpenTelemetry предлагает эффективный способ решения этих проблем.

OpenTelemetry

OpenTelemetry - это стандарт для реализации телеметрии в ваших приложениях. Он предоставляет спецификацию, содержащую требования, которым должны следовать все реализации, а также некоторые реализации для основных языков, включая API и SDK для взаимодействия с ним. OpenTelemetry родился в результате слияния двух других стандартов, которые решили объединить силы, а не соревноваться друг с другом, это были проекты OpenTracing и OpenCensus. Это вносит зрелость в стандарт, поскольку оба предыдущих проекта уже были зрелыми и прошли производственные испытания. Еще один важный факт - OpenTelemetry является частью Cloud Native Computing Foundation (CNCF). На момент написания этой статьи проект все еще оставался Sandbox Project. Чтобы упомянуть важность этого, другие очень известные проекты начинались так же, как OpenTelemetry, в том числе: Kubernetes, Prometheus и Jaeger (которые мы будем использовать позже).

Наверное, самое интересное в OpenTelemetry - это его архитектура. Он был спроектирован так, что его можно было легко расширить. Это касается последнего пункта в нашем списке. OpenTelemetry позволяет с минимальными усилиями переходить от одного поставщика к другому. Он использует концепцию экспортеров, это реализация конкретного поставщика для того, как отправлять данные, собранные в конкретный сервер. Поэтому, если вы хотите перейти с Jaeger на Zipkin, вам нужно только изменить экспортер, который вы используете, и ничего больше. Это отделяет остальную реализацию от вашей кодовой базы. Это также помогает реализовать наблюдаемость с самого начала разработки, даже до выбора серверной части для журналов, метрик и трассировок. Согласно их сайту:

OpenTelemetry делает надежную портативную телеметрию встроенной функцией облачного программного обеспечения.

Распределенная трассировка

Журналы и метрики очень полезны и достаточно просты в использовании, когда у нас есть единая система. Однако при работе с распределенными системами все начинает усложняться. Сопоставить вещи непросто. Иногда симптом может проявляться в одной системе, но настоящая основная причина может быть в другой системе, и если у вас нет надлежащей корреляции, вы можете никогда не узнать, что случилось с данным запросом или транзакцией. Вот где на помощь приходит распределенная трассировка. Распределенная трассировка, как следует из названия, - это метод, который позволяет нам отслеживать запросы в нескольких системах, где эти запросы так или иначе связаны. Обычно трассировки (или промежутки) содержат полезную информацию, такую ​​как временные метки и даже сообщения журнала. Это очень помогает при устранении проблем с производительностью или даже понимании того, почему данный запрос не удался и где возникла проблема.

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

Хотя OpenTelemetry имеет возможность собирать и экспортировать метрики (а в последнее время и журналы), мы не будем углубляться в эти темы в этих статьях.

Следующая статья и демонстрационное приложение

В следующей статье мы сосредоточимся на реализации некоторых сервисов в различных технологиях, использовании OpenTelemetry SDK, отправке (экспорте) данных в Jaeger. Вот обзорная диаграмма архитектуры решения из следующей статьи:

Демонстрационное приложение будет состоять из клиентского приложения (client), написанного на go, которое также будет взаимодействовать через gRPC с веб-приложением (weather), написанным на go. Приложение погода будет связываться через HTTP с другим веб-приложением (температура), написанным на C #. Используя эту настройку, мы можем исследовать пару интересных вещей с помощью OpenTelemetry. Первый - увидеть реализацию на разных языках, что приятно. Но наиболее интересным, на мой взгляд, является распространение контекста с использованием разных языков (golang и C #) и разных протоколов (gRPC и HTTP). Все приложения собираются записывать события на своих участках и отправлять все на наш распределенный сервер трассировки Jaeger.

Чтобы начать настройку среды, в которой будет запускаться эта демонстрация, давайте установим (запустим) и настроим Jaeger.

Установка и настройка Jaeger

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

docker run -d --name jaeger \
  -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
  -p 5775:5775/udp \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 14268:14268 \
  -p 14250:14250 \
  -p 9411:9411 \
  jaegertracing/all-in-one:1.18

Чтобы проверить, работает ли он, вы можете использовать URL-адрес http: // localhost: 16686 / для доступа к Jaeger Frontend (службе запросов).

Теперь, когда у нас настроен Jaeger, мы можем приступить к разработке и запуску сервисов, составляющих демонстрацию.

В следующей статье мы рассмотрим детали реализации каждой службы и то, как связать все запросы, чтобы они были видны под одной и той же трассировкой на Jaeger.