Одной из важнейших задач при разработке приложений с микросервисной архитектурой является задача мониторинга. Слежение за состоянием сервисов и серверов позволяет не только вовремя реагировать на неисправности, но и анализировать их работу. Наличие такой информации трудно переоценить, ведь она предоставляет дополнительные возможности по улучшению производительности и качества работы Вашего ПО.
К счастью, существует множество решений задачи мониторинга, как платных, так и бесплатных. Я же хочу поделиться опытом практического использования open source системы мониторинга Prometheus.
Знакомство с Prometheus
Всерьез с микросервисной архитектурой я столкнулся совсем недавно, начав работу с уже существующей инфраструктурой сервисов. Для слежения за состоянием серверов и сбора метрик использовался Zabbix. Конфигурацией Zabbix занимались администраторы и все изменения/добавления графиков должны были проходить через них. Такой подход позволяет разделить зону ответственности, особенно в случаях, когда одной системой мониторинга пользуются разные команды разработчиков. Но, в то же время, приводит к задержке или неточностям при добавлении новых графиков, ведь администратор может не обратить внимание на детали, очевидные для поставившего задачу разработчика или попросту будет занят другими задачами. Проблема становится особенно острой, когда для дальнейшей разработки требуется быстрый доступ к историческим данным по метрикам сервиса. В качестве средства решения этой проблемы, я решил поискать легкую и простую в настройке систему мониторинга, которая бы хорошо “ложилась” на уже существующую инфраструктуру и упрощала работу по анализу метрик.
Минимальная конфигурация системы мониторинга Prometheus состоит из сервера Prometheus и отслеживаемого приложения, достаточно только указать по какому адресу необходимо запрашивать метрики. Сбор метрик выполняется согласно pull-модели по протоколу HTTP, но существует и push-gateway компонент для слежения за короткоживущими сервисами. При использовании pull-модели Ваши приложения не знают о системе мониторинга, а значит можно запускать несколько серверов Prometheus для мониторинга, тем самым застраховавшись от возможных потерь данных. Для подготовки приложений к дальнейшему мониторингу предлагается использовать клиентские библиотеки, реализующие необходимый инструментарий по созданию и выводу метрик для различных языков. Рекомендуется использовать именно их, но при этом Вы можете применить свою реализацию, если она будет удовлетворять спецификации exposition formats.
Такой подход полностью удовлетворял моим требованиям, так как сбор метрик для Zabbix производился по схожей схеме. Для сохранения совместимости с Zabbix и с уже используемой библиотекой метрик был написан адаптер, преобразовывающий существующий формат в подходящий для Prometheus. Такое решение позволило безболезненно экспериментировать с Prometheus не “задевая” мониторинг в Zabbix и сохраняя стабильность работы существующих сервисов.
Использование
Преимущество использования Prometheus обнаружилось сразу же. Возможность в любой момент получать динамику изменения метрики, сравнивать с другими, преобразовывать, просматривать их в текстовом формате или в виде графика не покидая главной страницы web-интерфейса трудно переоценить.
Для фильтрации и преобразования метрик используется очень удобный язык запросов. К сожалению, отсутствует возможность сохранить сформированный запрос непосредственно через web-интерфейс. Для этого нужно создавать консоль, представляющую собой html-страницу, с возможностью использования Go-templates, и уже в ней строить графики, таблицы, сводки и т.д.
Хорошим решением будет создание обобщенных консолей. К примеру, необходимо мониторить несколько HTTP-серверов. Каждый из них имеет метрику, например, “http_requests_total”, показывающую количество принятых HTTP-запросов. Создадим консоль, отображающую список таких сервисов в виде ссылок на консоли с более подробной информацией:
{{ range query "sum(http_requests_total) by (instance)" | sortByLabel "instance" }}
<a href="/consoles/job-overview.html?instance={{ .Labels.instance }}">{{ .Labels.job }}</a>
{{ end }}
В результате, мы получим список из ссылок на консоль “job-overview.html”, в которую передается параметр «instance». Теперь этот параметр можно использовать в качестве фильтра для построения графиков:
new PromConsole.Graph({
node: document.querySelector("#successGraph"),
expr: [
"sum(http_requests_success{instance='{{ .Params.instance }}' })"
],
name: http_requests_success,
})
Как источник дополнительных примеров можно использовать стандартный набор консолей.
Производительность
Как утверждают разработчики, один сервер Prometheus может с легкостью обслуживать миллионы time-series. Этого достаточно для сбора данных с тысячи серверов с интервалом в 10 секунд. В случаях же, когда этого недостаточно — предусмотрена возможность масштабирования.
На практике заявленная производительность подтверждается. При мониторинге 800 сервисов, около 80 метрик в каждом, Prometheus использует около 6% одного ядра и 3 GB RAM, а собранные за 15 дней метрики занимают 17 GB памяти на диске. Не обязательно выделять для Prometheus отдельный сервер, с таким незначительным потреблением ресурсов он может быть установлен рядом с другими сервисами не принося никаких неудобств.
Prometheus хранит собранные метрики в оперативной памяти и при достижении лимита по размеру, или по прошествии определенного интервала времени, сохраняет их на диск. В случаях, когда приходится собирать большое количество данных (больше 100к time series, к примеру) может возрасти нагрузка на диск. В документации Prometheus приводятся полезные советы по оптимизации в таких случаях.
Бывают случаи, когда нужно сформировать график, требующий тяжелых вычислений, захватывающий большие временные периоды или имеющий высокое посещение. Для того, чтобы облегчить работу Prometheus и не вычислять такие данные на каждом запросе, существует возможность предварительного расчета. Такая опция будет особенно полезной при создании дашбордов.
Кастомизация
Откровенно говоря, web-интерфейс показался мне немного “сыроватым”. При работе с графиками, метриками, разделом наблюдаемых сервисов (/targets) возникала необходимость дополнительного функционала. С этим не возникло никаких проблем, и, вскоре, я добавил возможность быстрого поиска по тэгам метрик, а так же изменил layout раздела консолей. Когда раздел /targets увеличился до 800 сервисов — пришлось скрыть эндпоинты на странице, объединив их в группы (иначе они занимали слишком много места). Когда какой-то из эндпоинтов перестает нормально работать, то к группе добавляется иконка, уведомляющая об ошибке. Развернув лист, можно найти проблемный эндпоинт и узнать подробную информацию об ошибке:
Простота web-интерфейсов Prometheus открывает широкие возможности для создания themes, модифицирующих стандартный интерфейсы или добавляя новые разделы. Как подтверждение сказанного, предлагаю ознакомится с графическим генератором конфигурации.
Дополнительное ПО
Команда разработчиков Prometheus создает максимально открытый для интеграции проект, который можно использовать совместно с другими технологиями, а комьюнити всячески старается в этом помочь. На сайте Prometheus Вы сможете найти перечень поддерживаемых exporters — пакетов, снимающих метрики с других сервисов и технологий. Мы используем только некоторые: node_exporter, postgres_exporter и grok_exporter. Для них построены обобщенные консоли, графики в которых строятся относительно просматриваемого сервиса. Все ново добавленные или обнаруженные (service discovery) сервисы автоматически становятся доступными для просмотра в ранее созданных консолях. Если у Вас целый “зоопарк” технологий, то придется установить массу exporters для их мониторинга, но такому подходу есть вполне логическое обоснование.
Странной может показаться ситуация с безопасностью. Изначально, сервис Prometheus и установленные exporters “открыты миру”. Любой желающий, знающий нужный адрес и порт, сможет получить данные по вашим метрикам. Позиция разработчиков здесь такова — Prometheus это система мониторинга, а не безопасности. Пользователям не составит труда использовать в этих целях сторонние 3rd-party продукты, давно и успешно реализовывающие такие задачи, позволив разработчикам Prometheus сфокусироваться на задачах мониторинга. В моем же случае, успешно используется Nginx как reverse-proxy с http basic auth, настройка которого заняла совсем незначительное время.
Для тех, кто хочет лишить себя сна и покоя, разработчики предоставляют возможность использования AlertManager. Он чрезвычайно прост в настройке и позволяет работать с уже упомянутым языком запросов. AlertManager может интегрироваться с HipChat, Slack, PagerDuty, а в случае необходимости интеграции с еще не поддерживаемыми сервисами, рекомендую ознакомиться со статьей интеграции для аудио-оповещения.
В качестве практического примера привожу правило из моей текущей конфигурации AlertManager:
ALERT nodeexporter_available_disk_space
IF (100 - node_filesystem_free{job=~".*nodeexporter"} / node_filesystem_size{job=~".*nodeexporter"} * 100) > 70
ANNOTATIONS {description="Used disk space: {{ $value }}%. Device: {{ $labels.device }}.", summary="Running out of disk space at instance {{ $labels.instance }}"}
Это правило сработает в случае заполнения дискового пространства более чем на 70% на любом из серверов, где запущен node_exporter, после чего будет выслано соответствующее уведомление на почту.
Заключение
Я рекомендую Вам непременно познакомиться с Prometheus ближе. Для меня он стал легкой, простой и понятной системой мониторинга, с которой просто приятно работать, расширять и модифицировать под свои нужды. Если у кого-то возникнут вопросы относительно практического применения — буду рад ответить в комментариях.
Полезные ссылки
- Demo
- www.robustperception.io
- www.reddit.com/r/PrometheusMonitoring
- Report on Prometheus Casual Talks in Tokyo and then toward PromCon 2016
- Мониторинг сервисов с Prometheus
Автор: hagen1778