Periskop — это инструмент для мониторинга исключений, созданный в SoundCloud. Он разрабатывался специально для микросервисных архитектур, хотя может быть полезен и для других окружений с долго выполняющимися сервисами (long-running service). Periskop изначально проектировался с учетом масштабирования и во многом основан на нашем опыте с Prometheus. Исключения эффективно агрегируются на клиенте с помощью pull-модели, после чего они собираются на сервере и агрегируются по инстансам.
Зачем нужна еще одна система агрегации исключений?
Раньше в SoundCloud для поиска и устранения проблем в продакшне использовался Airbrake. Но при увеличении трафика, когда наши сервисы стали получать десятки тысяч запросов в секунду, небольшие подвисания стали генерировать большое количество сообщений об исключениях, что, в свою очередь, исчерпывало весь наш месячный бюджет всего за несколько минут и приводило к потере информации. Поиск в логах и их индексация также были затруднены из-за их огромного объема.
Учитывая постоянно увеличивающееся количество сервисов SoundCloud, нам было необходимо решение, которое легко бы обнаруживало сервисы и извлекало данные с минимальным ручным трудом.
Так как сотрудникам SoundCloud предоставляется возможность использовать до 20% времени для экспериментов с новыми идеями, то это была прекрасная возможность группе инженеров собраться вместе и создать что-то интересное и полезное для улучшения инструментов, используемых в SoundCloud и, надеюсь, принести пользу для всего сообщество разработчиков ПО с открытым исходным кодом.
Как это работает?
Periskop состоит из клиентской и серверной частей.
Клиентская часть осуществляет сбор исключений. При обработке исключения оно добавляется в коллектор (collector). Необработанные исключения могут быть добавлены в коллектор с помощью обработчика исключений верхнего уровня. Работает это следующим образом:
Коллектор создает уникальный ключ на основе текста исключения и хеша стек-трейса. Этот ключ представляет конкретный тип исключения.
Коллектор агрегирует исключения с помощью уникального ключа и сохраняет этот агрегат в памяти.
Конкретное событие исключения добавляется к списку недавних исключений агрегата. Для реализации скользящего окна последних исключений используется очередь с настраиваемым размером окна.
Собранные агрегаты исключений экспортируются через конечную точку HTTP с использованием хорошо известной схемы.
Серверная часть для поиска инстансов использует обнаружение сервисов (service discovery). Собранные исключения скрейпятся и агрегируются по экземплярам. Простой пользовательский интерфейс позволяет просматривать и анализировать исключения по мере их возникновения.
Компромиссы
В любом проектном решении есть ряд компромиссов, о которых важно знать. В случае Periskop мы выбрали pull-модель для сбора исключений, а не push, используемую в таких инструментах, как Sentry. Pull-модель лучше масштабируется с увеличением количества исключений и экземпляров и предоставляет интересные возможности, в частности:
Память, используемая клиентской частью, ограничена количеством различных типов возникающих исключений, а не общим количеством исключений. Память на стороне сервера также расходуется экономно, поскольку в ней используется та же логика агрегирования.
Если серверному компоненту необходимо отскрейпить большое количество инстансов, то он может пропустить циклы скрейпинга, тем самым уменьшив актуальность данных, но не требуя дополнительных ресурсов. На практике это означает, что Periskop может работать с большим количеством сервисов и экземпляров, потребляя небольшое количество ресурсов.
Создание иерархии экземпляров Periskop (известное как federation) становится тривиальным. Основной экземпляр Periskop может агрегировать исключения, собранные вторичными экземплярами, и, таким образом, обеспечивая глобальное представление всего стека сервисов.
Pull-модель также имеет некоторые недостатки по сравнению с push-моделью:
Если возникает фатальная ошибка и процесс завершается, то исключение не будет собрано. Эта проблема частично решается за счет возможностей сервисов оркестровки, таких как Kubernetes, или других вариантов обработки логов.
Pull-модель не очень хорошо подходит для кратковременных процессов, таких как периодически запускаемые задания. Это решается с помощью push-based шлюза событий (event gateway). Хотя в SoundCloud в этом сейчас нет необходимости, так как для проверки упавших заданий удобнее использовать логи.
Что дальше
Periskop еще совсем молодой и у него нет ряда возможностей. Вот некоторые из идей по его улучшению и развитию, которые включены в дорожную карту:
Долговременное сохранение исключений на стороне сервера.
Фильтрация и сортировка в UI.
Federation (иерархия серверов Periskop).
Плагины для обнаружения сервисов (service discovery).
Коннекторы к другим системам мониторинга ошибок, таким как Sentry.
Также, для реализации всего потенциала Periskop, необходимо разработать высокоуровневые библиотеки для наиболее популярных веб-фреймворков и клиентские библиотеки для большего количества языков программирования.
У Periskop открытый исходный код и мы рады внешним контрибьюторам. Если вы считаете этот проект полезным, то мы будем рады услышать вас. Пожалуйста, напишите нам periskop-maintainers@soundcloud.com.
В преддверии старта курса «Нагрузочное тестирование» приглашаем всех желающих посетить бесплатный демо-урок «Проведение нагрузочного тестирования в средстве Performance center».
В рамках урока участники рассмотрят интерфейс Performance center, создадут сценарий нагрузки, настроят планировщик запуска тестов.