опубликовано: 01.02.2019
Суть: Трейсинг упрощает дебаг и тестирование, внедрить его крайне просто.
ProppelerAds доставляет рекламу пользователям. Нагрузка на систему 200 000 запросов в секунду.
10 лет назад был монолит, который принимает на себя все запросы, если в ввести в такой системе идентификатор, можно будет просмотреть что происходит с запросом с самого начала.
Сейчас сервисов очень много, баз много, команд много, технологий и языков тоже много. Писать свой фреймворк логирования для всех языков в компании, который позволял бы использовать общий идентификатор во всех сервисах дорого, а еще нужно и с командами всех сервисов договориться о едином формате.
Приходит запрос от пользователя, запросу присваивается id, который передается дальше всем сервисам, а сервисы отправляют данные о запросе в коллектор.
Trace-ID виден в хедере всех запросов, по нему можно искать в UI. Еще можно добавить TraceGroup(это как теги). По этим тегам группируются множества трейсов, это облегчает дебаг сложных страниц с множеством запросов.
Трейс — записанный запрос пользователя с длительностью. Он состоит из span`ов — запросов в другие сервисы, базы, вызовы функций и т.п. Они имеют иерархическую вложенность, контекст каждого span можно наполнять какими-то данными и метриками.
В качестве коллектора в компании используется Jaeger
, который написан на go. Этот коллектор занимается складированием span’ов. Стораджем может быть Cassandra
или ElasticSearch
.
В каждый хост/контейнер по udp отправляет span-ы в jaeger-agent
, который по Thrift протоколу отправляет все в jaeger-collector
. Коллектор все складывает с сторадж, информацию из которого отображает Jaeger UI
.
Кликая по запросу в UI можно увидеть какие подзапросы куда ходили, где были ошибки, что сколько времени занимает. Благодаря такой карте мы можем понимать что происходит в нашей системе в рамках запроса, как будто мы подключились дебагером к нашей системе.
На основе span’ов Jaeger
строит граф зависимостей сервисов.
В PropellerAds используют OpenCensus, потому что большая часть бекенда написана на go, а с ним у OpenCensus хорошая интеграция. Так же у OpenCesus
есть экспортеры для разных систем: Jaeger
, Zipkin
, Stackdrive
. Есть готовые middleware для http, db, grpc. Поддерживает множество стораджей, интегрируется парой строчек в коде.
Сейчас в PropellerAds обрабатывается примерно 6-7 тысяч span в секунду на 1 инстансе Jaeger
и двух инстансах Elastic
.
Если есть Envoy, в него можно добавить трейсинг парой строк в конфиге, после чего Envoy будет трейсить запросы всех серсисов, которые он оборачивает.
Управляют трейсингом через Consul
, в котором настраивают для какого пользователя или, например, страны, нужно включать трейсинг.
Трейсинг обычно запускают не для всего трафика, чтобы тратить меньше ресурсов.
Интегрировать во все сервисы на Go получилось буквально за пару вечеров.
Пришлось писать обертку над сообщениями для кастомных протоколов, кафки, где нет заголовков, передающих Trace-ID.
Если приложение порождает очень много спанов, то их объем может не влезть в захардкоженный максимальный размер датаграммы, передаваемой по UDP, в локальный агент. Сейчас эта проблема агента исправляется, обойти можно прямой отправкой спанов в коллектор.
TraceID
от Jaeger
и TraceID в PHP отличались, из-за этого трейс
разъезжался. Решается через установку bcmath для PHP и обновлением opencensus-php-exporter-jaeger
до 0.1.1 Так же для PHP нужно пересылать все по UDP, потому что PHP блокирующийся язык, а UDP позволяет нам не ждать отправки запроса.
Есть жалоба, что сайт очень медленно открывается. Открываем графану, видим, что сайт открывается за 225мс, все нормально. Смотрим логи, там ошибок тоже нет. Понятно, что система работает, но что в ней приохотит и где что не так совершенно не ясно.
Включили трейсинг для пользователя, это дало подробную информацию о его запросах, понимание, в каком сервисе сколько времени ждем ответа. Так поняли, что проблемы с бекендом нет, начали проверять фронтенд, нашли проблему с гугланалитикой.
Трейсинг облегчает интеграционное тестирование, за счет того тестировщик может отдать разработчику Trace-ID, по которому разработчик продолжить дебажить. Некоторые тестировщики теперь даже могут исправлять проблемы, по трейсингу они понимают, как система работает.
На уровне приложения через библиотеки для ORM, которые будут логировать запросы к базам.
Диагностировать внутренние проблема tracing не позволяет, но можно в его метадате посмотреть на каком сервере он выполняется.
Если вы агрегируете логи для счетчиков и делаете алерты, то трейсинг это заменить не сможет, алертов тут нет. Но такие вещи можно вынести в мониторинг, оставить системные логи, а все остальное покрыть tracing`ом.
3-5% на сборку мусора в go. На графиках распределения запросов по времени ответа в 99 перцентиле нет никакой разницы. Разница может появится в случае складывания больших данных и большом проценте семплирования при большом количестве запросов.
Можно использовать StackDrive от Google.
Для первого добавления хватит подключения внешнего сервиса к middleware. Это покроет 80-90% проблем.
Включили трейсинг для пользователя, убедились, что все работает быстро. Поняли, что проблема не в нашей системе, а где-то на фронтенде.
Я консультирую о том о чем пишу, связаться со мной можно через telegram @aladmit или по почте [email protected]