Модуль 2 · как работает prometheus · сбор метрик
Глава 2.5
Pull-модель:
запрос идёт от сервера
В предыдущих главах запрос шёл от Prometheus к приложению. Такой порядок называется pull-моделью. В этой главе он сравнивается с обратным порядком — push. Разобрано, кто начинает обмен, откуда взялась pull-модель, что она даёт и чем ограничена. В конце показано, как поступают, когда pull не подходит.
- Категория
- Способ сбора
- Уровень
- Средний
- Опирается на
- Главы 2.2–2.4
- Результат
- Выбор способа сбора для сервиса, задачи или устройства
§1Два способа доставки метрик
Во всех предыдущих главах обмен начинал сервер: Prometheus отправлял запрос, приложение отвечало. Это не единственный возможный порядок. Числа появляются в приложении, а хранятся на сервере мониторинга, и доставить их можно двумя способами. Различаются способы тем, кто делает первый шаг.
Первый способ. Жилец раз в месяц передаёт показания в управляющую компанию.
Второй способ. Контролёр обходит квартиры по списку и записывает показания.
Когда жилец уехал, в первом случае компания не получает письма, и причина ей неизвестна. Во втором случае у контролёра записано, в какую квартиру он не попал.
Push. Приложение отправляет числа на сервер мониторинга.
Pull. Сервер обходит приложения по списку target и забирает числа.
Когда приложение остановилось, при push сервер не получает данных, и причина ему неизвестна. При pull на сервере записано, какой target не ответил: ряд up равен 0.
У способов есть названия. Когда числа отправляет приложение, это push-модель: в приложении записан адрес сервера, и оно отправляет данные по своему расписанию. Так работают StatsD, Graphite, InfluxDB в обычной настройке и протокол OTLP из OpenTelemetry. Когда числа забирает сервер, это pull-модель: на сервере записаны адреса приложений, и он опрашивает их по своему расписанию. Так работает Prometheus: scrape из главы 2.4 устроен по этой модели.
В сравнении со счётчиком воды разница проявилась в момент, когда жилец уехал. Следующий раздел показывает тот же момент по шагам.
§2Push и pull по шагам
Две схемы показывают одну ситуацию: проходят два обмена данными, затем приложение аварийно завершается. До остановки схемы различаются только направлением стрелок. Содержательное различие появляется на последнем шаге, поэтому сравните, какие сведения есть у сервера после остановки приложения.
При push сервер после остановки ничего не получает и не может отличить остановленное приложение от приложения, у которого нет новых чисел. При pull сервер отправляет запрос, получает ошибку соединения и записывает up = 0. На сервере записаны адрес, который не ответил, и момент, с которого это началось.
Этим различия не исчерпываются. Из того, кто начинает обмен, следует ещё несколько свойств, и они собраны в таблице.
| Вопрос | Push | Pull |
|---|---|---|
| Где записан адрес другой стороны | В приложении записан адрес сервера | На сервере записаны адреса приложений |
| Кто задаёт время передачи | Приложение | Сервер: scrape_interval |
| Как узнают об остановке приложения | По отсутствию данных. Нужна отдельная проверка | По неуспешному scrape: up = 0 |
| Кто управляет нагрузкой на сервер | Приложения. Тысяча приложений может отправить данные одновременно | Сервер. Он распределяет опросы по интервалу |
| Какое соединение должно быть разрешено | От приложения к серверу | От сервера к каждому приложению |
| Задача, которая работает 3 секунды | Успевает отправить результат | Может завершиться до первого scrape |
В двух строках таблицы упомянуты соединения и адреса. Следующий раздел разбирает эти направления отдельно.
§3Направление запроса и данных
Слово pull означает «тянуть», и из-за него кажется, что всё движется в одну сторону. Направлений два. Запрос идёт от Prometheus к приложению, а данные идут обратно, от приложения к Prometheus. При этом соединение одно, как в телефонном звонке в справочную: человек звонит и задаёт вопрос, ответ слышит в том же разговоре, и справочная ему не перезванивает.
Соединение открывает Prometheus, а приложение его только принимает. Отсюда два практических следствия. Первое касается сети: сетевой экран между ними должен разрешать одно соединение, от Prometheus на порт приложения. Второе касается безопасности: порт приложения принимает входящие соединения, а на странице /metrics видны внутренние числа сервиса. Поэтому этот порт не открывают в интернет, и метрики отдают на внутреннем адресе сети.
Подробнее: защита страницы /metrics
Страницу можно закрыть шифрованием и проверкой доступа. В задании Prometheus для этого есть параметры scheme: https, tls_config, basic_auth и authorization.
Устройство pull разобрано. Прежде чем оценивать его преимущества и ограничения, следующий раздел рассказывает, откуда оно взялось.
§4Откуда взялась pull-модель
Pull-модель Prometheus повторяет устройство системы Borgmon — внутренней системы мониторинга компании Google, описанной в главе 10 книги Google «Site Reliability Engineering» (2016). Программы Google отдавали свои числа по адресу /varz обычным текстом: в каждой строке название и значение. Пример из книги:
% curl https://webserver:80/varz http_requests 37 errors_total 12
Сходство с Prometheus есть не только в странице. По описанию в книге, Borgmon опрашивал /varz через заданные интервалы — в Prometheus это scrape_interval. Список target он получал из службы имён — в Prometheus это service discovery. Опросы он распределял по интервалу, и для каждого target записывал переменную «удался ли опрос» — в Prometheus это ряд up. В той же главе книги Prometheus назван среди открытых систем, похожих на Borgmon.
Внутренняя система с опросом по HTTP. По книге SRE, основа мониторинга Google почти 10 лет.
Открытая система с тем же способом сбора и метками.
Формат из главы 2.3 появился в апреле 2014 года.
Prometheus принят в фонд Cloud Native Computing Foundation вторым после Kubernetes.
В Google эта модель работала почти десять лет. Следующие два раздела разбирают, что она даёт и чем ограничена.
§5Что даёт pull
Создатели Prometheus объясняют выбор pull в разделе вопросов и ответов документации:
«Pulling over HTTP offers a number of advantages: You can start extra monitoring instances as needed, e.g. on your laptop when developing changes. You can more easily and reliably tell if a target is down. You can manually go to a target and inspect its health with a web browser.»
В ответе названы три преимущества, и каждое из них уже встречалось в модуле. Первое: можно запустить ещё один сервер мониторинга, например на своём ноутбуке, и в приложении для этого ничего не меняют. Второе: проще и надёжнее определить, что target не работает, — это ряд up и текст ошибки из главы 2.4. Третье: target можно открыть в браузере и проверить вручную, потому что браузер и curl получают тот же текст, что и Prometheus.
К этим трём на практике добавляются ещё два. Нагрузкой управляет сервер: он распределяет опросы по интервалу, и тысяча приложений не отправляет ему данные одновременно. Список target к тому же показывает, что должно работать. Target из списка, который не ответил, виден как DOWN, а при push приложение, которое ни разу не отправило данные, серверу неизвестно.
Проще становится и приложение. Ему не нужен адрес сервера мониторинга, не нужно хранить неотправленные данные и повторять отправку, когда сервер недоступен. Библиотека хранит числа в памяти и отдаёт их по запросу.
Все пять преимуществ следуют из того, что обмен начинает сервер. Из того же следуют и ограничения.
§6Ограничения pull
Ограничений три, и у каждого есть принятый способ его обойти.
Сервер должен иметь доступ к target. Если приложение находится в закрытой сети, куда входящие соединения запрещены, Prometheus его опросить не может. Документация советует в таком случае ставить Prometheus в ту же сеть, что и приложение.
Нужно знать список target. В облаке копии сервиса появляются и исчезают, и файл с адресами быстро устаревает. Эту задачу решает service discovery из главы 2.2: список берут из внешней системы.
Короткая задача завершается раньше scrape. Скрипт резервного копирования работает 40 секунд и завершается. При интервале 60 секунд scrape может не попасть в эти 40 секунд, и результат задачи в Prometheus не попадёт. Для этого случая есть отдельная программа, Pushgateway, и она разобрана ниже.
Как работает Pushgateway
Идея Pushgateway знакома по почтовому ящику в подъезде. Жилец уезжает до прихода контролёра и оставляет записку с показаниями в ящике, а контролёр забирает её при обходе. Короткая задача так же перед завершением отправляет числа в Pushgateway. Pushgateway работает постоянно, и Prometheus забирает числа оттуда при очередном scrape, как у обычного target.
На схеме две стрелки направлены к Pushgateway с разных сторон: задача отправляет в него данные способом push, а Prometheus забирает их способом pull. Из-за этого посредника теряются три свойства pull, и документация их перечисляет.
Во-первых, появляется одна точка отказа: если через один Pushgateway отправляют данные много задач и он остановится, пропадут данные всех. Во-вторых, для задачи нет ряда up: этот ряд показывает доступность самого Pushgateway, а состояние задач по нему определить нельзя. В-третьих, данные не удаляются сами. Pushgateway хранит последние полученные числа и отдаёт их при каждом scrape, пока их не удалят вручную, так что числа удалённой копии сервиса остаются. При pull они исчезли бы вместе с копией.
Поэтому документация советует Pushgateway только в одном случае: для результата пакетной задачи, которая относится ко всему сервису и не привязана к одной машине. Пример — ночная очистка базы данных.
Подробнее: настройки для Pushgateway и другие решения
У метрик такой задачи не должно быть метки instance. Pushgateway передаёт метки job и instance других программ, поэтому в его задании включают honor_labels: true (глава 2.2, §6).
Для задач, привязанных к одной машине (cron, обновления), числа записывают в файл. Этот файл читает программа node exporter через свой textfile collector.
Для приложений в закрытой сети есть PushProx. Его клиент внутри закрытой сети держит соединение с посредником, и Prometheus опрашивает приложение через посредника.
Pushgateway — один из случаев, когда в системе на основе pull используется push. Последний раздел собирает все такие случаи.
§7Push в экосистеме Prometheus
Основной способ сбора в Prometheus — pull, но передача данных способом push встречается в четырёх местах. Они перечислены в таблице; флаги запуска из неё проверены командой prometheus --help версии 3.5.0.
| Механизм | Кто кому отправляет | Для чего |
|---|---|---|
| Pushgateway | Задача → Pushgateway. Prometheus опрашивает Pushgateway способом pull | Результаты коротких задач |
remote_write в конфигурации | Prometheus → другое хранилище | Долгое хранение и объединение данных нескольких серверов |
Флаг --web.enable-remote-write-receiver | Другой Prometheus → этот Prometheus | Приём данных от серверов, которые опрашивают свои target |
Флаг --web.enable-otlp-receiver | Приложение с OpenTelemetry → Prometheus | Приём метрик по протоколу OTLP без страницы /metrics |
Оба флага по умолчанию выключены. У данных, принятых через них, тот же недостаток, что был у push в §2: они не проходят scrape, для их источников нет ряда up, и доступность отправителя приходится проверять отдельно.
Какой способ выбрать
Материал главы сводится к порядку выбора. Если программа работает постоянно и находится в той же сети — веб-сервис, обработчик задач, база данных, — её опрашивают способом pull: через страницу /metrics или через exporter. Это основной случай, и к остальным переходят, только когда он невозможен.
Для пакетной задачи всего сервиса используют Pushgateway: без метки instance и с honor_labels: true в задании. Задача cron на одной машине записывает числа в файл, который читает node exporter. Для приложения в закрытой сети ставят Prometheus в ту же сеть или используют PushProx. Если в приложении уже есть OpenTelemetry, метрики принимают по протоколу OTLP, а доступность приложения проверяют отдельно.
§8Проверьте себя
Вопрос 1Между Prometheus и приложением стоит сетевой экран. Какое соединение он должен разрешить для pull?
Так было бы при push. В pull приложение соединений не открывает.
Верно. Prometheus открывает соединение, а данные приходят в ответе по нему же.
Ответ идёт по уже открытому соединению. Второго соединения нет.
Вопрос 2Какое преимущество pull названо в документации Prometheus?
Объём одинаковый: передаются те же значения. Документация этого не утверждает.
Верно. Это одно из трёх преимуществ из документации, вместе со вторым сервером мониторинга и проверкой в браузере.
Закрытая сеть — одно из ограничений pull (§6).
Вопрос 3Скрипт очистки базы запускается раз в сутки и работает 20 секунд. Как передать в Prometheus время его последнего успешного запуска?
Scrape может не попасть в 20 секунд работы. После завершения скрипта target будет DOWN до следующих суток.
Верно. Это пакетная задача всего сервиса — случай, для которого документация советует Pushgateway.
Prometheus логи не читает. Для логов нужны другие системы.
Вопрос 4Копия сервиса удалена. Что станет с её числами в Pushgateway?
Pushgateway не связан с работой копий и полученные числа не удаляет.
Верно. Документация называет это одним из недостатков Pushgateway.
Ряд
upотносится к самому Pushgateway. Для копий, которые в него писали, отдельногоupнет.
- Prometheus. FAQ: Why do you pull rather than push? — prometheus.io/docs/introduction/faq
- Prometheus. When to use the Pushgateway — prometheus.io/docs/practices/pushing
- Beyer B. и др. Site Reliability Engineering. Глава 10. Practical Alerting from Time-Series Data — sre.google/sre-book/practical-alerting
- Prometheus. Overview — prometheus.io/docs/introduction/overview
- PushProx — github.com/prometheus-community/PushProx
- Флаги
--web.enable-remote-write-receiverи--web.enable-otlp-receiverпроверены вprometheus --help, образ prom/prometheus:v3.5.0