Чем заменить New Relic: 11 аналогов и наш выбор

Это лишь часть таблицы альтернативных инструментов, которые мы рассматривали. Подробнее по ссылке.

Мы используем New Relic в каждом из наших 250 PHP-сервисов. С его помощью отслеживаем взаимосвязи между сервисами, их зависимости, смотрим нагруженные транзакции, анализируем полный трейс запроса пользователя. Наши основные функциональные требования: связи, оценка по времени отклика и параметру APDEX (собирательное значение удовлетворенности пользователя).

Отказаться от New Relic хотели давно. Главная причина — он стал дорогой. Весной добавилась вторая причина — мы из России. Хоть и оплачивали New Relic с кипрского юрлица, все равно запереживали, что нас могут отключить. А мы в команде инфраструктуры стараемся все сервисы держать на своей стороне.

В августе закончился договор с New Relic, так что заранее стали искать ему замену. И вот, как оно было.

С чего начали

70acc9f676e05e127c70019dd0a95e2b.jpg

Переезд оттягивали долго — задача большая и сложная. После 24 февраля взяли ее в план как целевую. Рассматривали все варианты: закрытые и опенсорс-аналоги New Relic. 

Изначально была идея найти дешевую замену в Пакистане или Индии — странах, которые придерживались нейтралитета в отношении России. Примеры таких сервисов: Atatus и Site24×7. 

Мы отправили им запрос про цены и, получив ответ, ужаснулись. Atatus зарядил прайс в 40000$ — это в 10 раз больше, чем мы платили за New Relic. Site24×7 тоже стоил бы дороже.

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

Главные минусы опенсорс-вариантов

  • Практически у всех отсутствует алертинг. Надо накручивать сверху, но с этим можно жить. 

  • В некоторых нет APDEX-метрики. А у нас разработчики к ней привыкли. 

Мы решили составить список важных нам характеристик, которые должны быть у инструмента. Я пошел в чат с разработчиками и попросил их назвать все, чем они пользуются в New Relic. Просмотрел ответы, отыскал старые аналогичные треды про возможный переезд, структурировал и выписал основные требования. Собралась первая колонка таблицы — с нужными характеристиками. Их 19. 

7b588fe9c239b12f705d6e26085d67fb.png

На всякий случай дублирую ссылку на таблицу.

Также мы добавили каждому требованию приоритет:

  • Желательно — если не будет, то мы не расстроимся или разработаем альтернативу.

  • Важно, но не критично — было бы приятно, но можно жить и без.

  • Критично — супер важное требование.

Для наличия / отсутствия нужных характеристик у аналогов, выбрали разные цвета:  

  • Зеленый — все в порядке.

  • Желтый — чего-то не хватает.

  • Красный или черный — у инструмента все плохо с характеристикой или мы протестировали его и он нам не подошел.

  • Фиолетовый — нет информации.

Если у сервиса критичный для нас параметр окрашивался в красный или черный — мы говорили ему «нет». Хотя были исключения, но об этом позже.

Я выписал все аналоги, которые нашел гуглением или которые рекомендовали. И начал сравнивать. По каждому выставлял: открытый / закрытый софт, облако / сервер, штаб-квартиру и так далее. Указывал стоимость, если цифра была в открытом доступе. Для опенсорс-решений мы старались найти примерный хост, который требуется для обеспечения минимальной жизнеспособности, и сделать десятикратный запас. Например, Apache SkyWalking стоит 200$ за стандартный хост. С запасом x10 — это 2000$.

У нас 98% бэкенда на PHP, поэтому была важна метрика поддерживаемых версии PHP. Нужно, чтобы инструмент поддерживал 7.2 — есть ряд старых проектов, хотя основная 7.4 и выше. И, конечно, важна поддержка 8.1. 

Еще был важен тип агента PHP, чтобы установить новое расширение и не устраивать переделку кода 500 сервисов.

В итоге, выбрали 2 опенсорс-кандидата.

Apache SkyWalking и Zipkin

Мы остановились на них, несмотря на отсутствие алертов. У Zipkin еще и нет APDEX-метрики. Но это то, с чем решили смириться и прикрутить при необходимости. 

Что дальше? Начали тестировать. Первым был Zipkin. Его название понравилось больше:)

Развернули сервер и посмотрели, как он выглядит снаружи. По сравнению с New Relic — печально, но терпимо. Для полной проверки решили собрать больше данных и подключить наши сервисы. У Zipkin есть бандлы, поддерживающие Symfony, но понадобилось расширение, которое на уровне PHP перехватывало бы запросы. И мы его нашли — Molten. 

Проблема — Molten давно не обновляется и не поддерживает ни PHP 8.1, ни 7.4. Последнее обновление библиотеки — полтора года назад, комментарии на китайском. От идеи двигать Zipkin дальше мы отказались…

Попробовали SkyWalking. Он показался более готовым к продакшену.

Подняли сервер на тестинге — все более-менее. Зашли в интерфейс — понравилось и даже похож на New Relic. Стали подключаться к сервисам и нашли огромный недостаток — расширение SkyWalking, которое мы использовали, не поддерживало консольные команды! Все консьюмеры и задачи, которые у нас запущены по Cron, никак не отображались. Я не мог понять, как такое возможно. Связался с контрибьютером. Оказалось, из-за архитектуры расширения, CLI плохо контролируется и его поддержка не реализована — пруф. А это для нас критичный момент.

1516227202a11f0a592304d01809d645.png

Снова вернулись к таблице альтернатив.

Elastic APM

Бесплатных вариантов не осталось, а из полуопенсорс только Elastic APM. Он требует лицензию. Мы рассчитывали, что она обойдется в 125$, плюс содержание своих серверов. Пообщавшись с Elastic, выяснили, что расклад следующий:

  • Стоимость одной ноды — 6000$ в год.

  • Минимальный контракт — 3 ноды.

  • Elastic насчитали, что нам нужно 5 нод.

Получается, Service Map стоил бы нам примерно 18–30 тысяч долларов в год. И, кажется, этот функционал лучше реализовать самим.

У Elastic APM есть PHP-расширение. Мы раскатили на тестинге и столкнулись даже с большим количеством проблем, чем в двух предыдущих вариантах:  

  • Нет внятной документации по развертыванию в Kubernetes. Пришлось звать DevOps-команду и разбираться. 

  • При поднятии на тестинге выяснилось, что Elastic APM заблокировал РФ. Например, чтобы внутри Kibana установить расширение для интеграции с Elastic APM, нужно подключиться к серверам Elastic Core, который блокирует любые запросы с нашей стороны.

Подумали и для интеграции подняли по инструкциям Elastic Registry, то есть свой сервер с этими же интеграциями. 

  • Невозможно купить лицензию. Владка спрятана, опять же по причине блокировки РФ. Нашли внутреннюю апишку и подключили триал.

Нам снова не хватало данных. Попробовали с инфровых сервисов, у которых много связей, слать данные на тестинг. Получилось, но столкнулись с недоработками PHP-расширения. 

Расширение работает стабильно, поддерживает PHP 7.2–8.1, можно нормально настроить конфигурацию и даже поставить дебаг-режим, чтобы получать сообщения об ошибках. 

Но:

  • Внутри пришлось отключить HTTPS.

  • Не поддерживается Symfony HTTP-клиент из-за отсутствия поддержки curl_multi.

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

  • Несколько запросов к разным базам данным лепятся в одну базу. Он их не умеет различить, сматчить и построить сервисную карту. 

Пришел август

Летом New Relic предупредили, что 30 августа переведут нас в режим read-only, поэтому обратного пути не было. 

5391c69c1b9f7cb5bac09c2ad518b503.jpg

Мы подняли публичную продовую версию Elastic APM внутри под VPN, определились с архитектурой и вырезали лишнее, чтобы сделать ее легковесной. Стали подключать сервисы к Elastic APM, смотреть на данные и сверять с New Relic. 

Единственное, что мы не нашли в Elastic APM — апишку, которая позволяет получать оттуда данные. Мы не можем по API запросить зависимые от сервисов сервисы. Поревесинженирили и нашли недокументированную API, которая дает данные для сервисной карты на фронт. 

О доработках на стороне расширения

Расширение работало стабильно с PHP 8.0 / PHP 7.2, но не было поддержки RabbitMQ и Symfony Messenger. Для того, чтобы видеть данные по очередям в Elastic APM, мы создали внутренний бандл для Symfony. В нем частично перенесли функционал, который у нас уже был написан для New Relic. 

Следующая проблема — в APM отсутствуют данные по запросам к сервисам кешей (Memcached, Redis). Начали смотреть, что с этим делать. Со стороны расширения это была большая доработка. Решили его не править, а позаимствовать внутри нашего бандла функционал, который использует Sentry для получения данных о запросах к кэшу.

Еще одна проблема — в Elastic APM не то чтобы отсутствует поддержка Symfony HTTP-клиента, просто он по умолчанию использует асинхронные операции, которые реализованы через curl_multi. А расширение Elastic APM не умеет обрабатывать curl multi. Даже в бэклоге нет задачи на поддержку этого. 

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

Внесли доработки и поняли, что если будем делать мерж-реквест в официальный Elastic-репозиторий, то это займет много времени, а уже нужно катить. Поэтому клонировали к себе в GitLab репозиторий Elastic и закомитили правки.

Затем еще сложности. Расширение не записывало дополнительные данные по запросу в БД (название базы, адрес и порт, по которому обращение) и не поддерживало Opcache preload. Тоже доделывали. 

Едем дальше.

На этом проблемы не закончились

Мы все еще используем New Relic и Elastic одновременно и они вроде не конфликтуют. Но если приложение подключается к другому Elastic по HTTP-соединению, то автоматический инструментарий New Relic и Elastic APM добавляют в header заголовок трейса, который по стандартам W3C должен быть один. А у нас получается два. И когда приходит запрос в Elasticsearch, то он выдает ошибки мультизаголовков. Выкатили для таких сервисов отдельный образ с отключенным New Relic и подготовили инструкцию по срочному переходу.

У нас постоянно сыпятся ошибки в логи контейнеров о том, что сервер не имеет HTTP-хост ключ. Это происходит из-за того, что есть хелсчеки, которые обращаются на 127.0.0.1. И у них во время запроса не определялся $_SERVER[«HTTP_HOST»], а Elastic APM думает, что это все равно внешний запрос, пытается найти HTTP_HOST, не находит его. Из-за этого у нас общий фон логов с одной и той же ошибкой возрос по всему Skyeng. Не сильно мешает, но и не очень красиво. В итоге, повысили уровень логирования в расширении до CRITICAL, так-как помимо инфраструктуры, разработчиков это тоже сильно нервировало.

Стали проходить не все тесты. Для раннего обнаружения ошибок в образах PHP мы не отключали полностью Elastic APM не на проде. Он работает, но ничего не отправляет. Во время тестов, когда большое количество миграций и прочего, Elastic APM падает по памяти. Ограничились тем, что те, у кого происходят такие проблемы, во время тестов добавляют отдельную энвайронмент-переменную Elastic AMP disabled instrumentations. APM работает, но автоматически ничего не записывает и не тратит память.

После того, как раскатилось около 50% сервисов (примерно 100), мы стали не справляться с нагрузкой. По памяти и по CPU Elasticsearch и Kibana тянули нагрузку хорошо, а APM-серверы, которые находятся в кластере на отдельных 10 подах, начали сильно загружаться. Нам пришлось увеличить количество подов, временно убрать им ограничение на память и CPU, а также включить автоматическое масштабирование, потому что поток данных потек большой.

Потихоньку подключались следующие сервисы. Мы начали готовиться к переносу алертов из New Relic в Elastic APM… И тут не обошлось без проблем. Мы до сих пор на бесплатной лицензии, а интеграции алертов со Slack и с веб-хуками, которые используются для связи с Opsgenie, — на Gold-версии. 

Еще Elastic APM не умеет алертить по отдельным транзакциям — только по целому сервису. Например, есть у сервиса отдельный эндпоинт, который отвечает долго. В New Relic можно было для него настроить отдельный порог срабатывания алерта, а в Elastic APM нужно настраивать алерт по среднему уровню по больнице. 

В результате, у Elastic APM либо всё время будет алертить медленный эндпоинт (порог настроен по быстрым эндпоинтам) или алертов просто не будет (порог настроен по медленному эндпоинту). У нас же принято, что все алерты настроены на определенные транзакции. Пока с помощью Grafana смогли получить данные из Elasticsearch по APM, вытащить оттуда данные по каждой из транзакций и настроить алерты. Но сложность в том, что Grafana постоянно запрашивает данные. Если сделать так для всех алертов — Elastic будет задыхаться. Решили таким способом выстраивать только критичные алерты.

Итоги

Положительные стороны Elastic APM и его расширения:

Что не очень:

Есть расширение и оно работает!

Поддерживает PHP 7.2–8.1.

Есть визуализация «из коробки».

Под капотом всё настроено для работы с данными APM.

Практически полное отсутствие возможности оптимизировать данные.

Отправлять только транзакции с ошибками или вне среднего времени выполнения нельзя.

Не поддерживается opcache.preload.

Для алертов в Slack и OpsGenie или для ServiceMap требуется Platinum лицензия.

В консьюмерах есть проблемы при работе расширения. Там его пришлось отключать.

Мы перевезли 180 сервисов. Остаются задачи по оптимизации хранения и дошлифовке расширения, но основной функционал уже production-ready. Дежурные инфраструктуры используют Elastic APM для расследования инцидентов — пару раз он им в этом сильно помог.

С 1 сентября мы остались без New Relic. Хорошо, что к этому моменту была альтернатива, хоть и в состоянии MVP. Возможно, работая над разработкой собственного расширения в связке с Prometheus Grafana, вместо поиска альтернатив, мы бы закончили разработку также. Но теперь наш путь — дорабатывать имеющиеся расширение вместе с ребятам из Elastic. 

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

Если же вы решили писать своё расширение — PHP Internals Book в помощь.

© Habrahabr.ru