Discord внедрил распределённый трейсинг в свою инфраструктуру Elixir, обеспечив видимость работы с миллионами пользователей. Это важно для разработчиков, так как подобное решение позволяет эффективно отслеживать и анализировать сообщения пользователей без ущерба для производительности.
Контекст: вызовы Elixir и распределённого трейсинга
Elixir, использующий акторную модель, сталкивается с уникальными проблемами в области мониторинга. В отличие от традиционных микросервисов, где контекст трейсинга передаётся через заголовки HTTP, в Elixir сообщения обмениваются без встроенного механизма метаданных.
Discord занимался поиском решения, которое отвечало бы трем основным требованиям: простота использования для разработчиков, поддержка как «сырых» сообщений, так и абстракций GenServer, а также возможность развертывания без остановки работы сервиса.
Решение: библиотека Transport и её особенности
Инженеры разработали библиотеку «Transport», которая оборачивает сообщения Elixir в так называемые «Конверты» с контекстом трейсинга. Это делается с помощью специального примитива, что позволяет легко интегрировать библиотеку в существующий код.
Процесс «упаковки» сообщений включает в себя структурирование оригинального сообщения и сериализированного носителя трейсинга. Библиотека также предлагает замены для функций GenServer, автоматизируя процесс упаковки исходящих сообщений.
Важным аспектом стала возможность обрабатывать переход от старых к современным сообщениям: это позволило Discord постепенно адаптировать систему, не прерывая работу.
Практическое значение для разработки
Внедрение трейсинга позволило Discord существенно повысить уровень мониторинга и анализа. В случае отправки сообщения в сообщество с миллионом пользователей создание бесконечного числа «дочерних» спанов—от одного сообщения благодаря динамическому выборочному учёту—стало основным вызовом. Текущая реализация настраивает выборку по количеству получателей: 100% для одного получателя, 10% для ста и всего 0,1% для более 10 000 получателей. Это помогает избежать нагрузки на систему мониторинга.
Команда столкнулась с повышенными нагрузками на CPU из-за необходимости разбирания контекста трейсинга. Решение заключалось в том, чтобы не передавать контекст, если операции не были выбраны для отслеживания, что существенно снизило затраты на обработку.
Перспективы разработки
Для разработчиков, работающих с Elixir, это решение открывает новые горизонты. Внедрение распределённого трейсинга без заметного влияния на производительность позволяет повысить надёжность и эффективность разработки. Discord, по всей видимости, продолжит развивать это направление, чтобы улучшить свою инфраструктуру.