Когда вы травите свой скот, вы обычно настраиваете проверку здоровья, чтобы сохранить жизнь вашему стаду. Очень часто livenessProbe выполняется GET запрос к конечной точке, и если служба отвечает two hundred, то все в порядке, в противном случае модуль уничтожается и запускается новый:

С Kafka Streams все не так просто. Приложение базовых потоков считывает данные из темы, выполняет преобразования и помещает их обратно в другую тему. В частности, он не раскрывает никакой информации о своем здоровье.

Давайте рассмотрим несколько возможностей, ни одна из которых не идеальна, чтобы выбрать наиболее подходящую для вашего случая. Если у вас есть другие или лучшие идеи, не стесняйтесь комментировать, я буду более чем счастлив продлить этот пост.

1. Создайте выделенную конечную точку HTTP.

Звучит довольно просто. Вместе с приложением Kafka Streams запустите Java HTTP Server, который предоставляет конечную точку проверки работоспособности для сообщения о состоянии потоков:

Затем настройте приложение потоков соответствующим образом:

Это прекрасно работает. Если поток запущен, что означает, что он находится в состоянии RUNNING или REBALANCING, приложение ответит кодом ответа 200, и Kubernetes не коснется модуля. В случае сбоя модуль будет повторно создан.

Недостатком этого подхода является включение HTTP-сервера в каждое приложение Kafka Streams.

2) Проверка работоспособности на основе JMX - 1-я попытка

Приложение Kafka Streams предоставляет метрики через JMX, если запущено со следующими параметрами:

Когда вы подключитесь к Java Monitoring & Management Console a.k.a. jconsole, вы получите доступ к нескольким показателям:

Нет, к сожалению, мы еще не закончили, так как статуса приложения среди них нет 🙈.

Один из способов решения этой проблемы - отслеживать метрику count в объекте kafka.streams:type=kafka-metrics-count. Если он выше 1.0, то я предполагаю, что поток запущен:

Мы выяснили, что когда поток умирает, значение count равно 1.0:

Как мы можем построить проверку здоровья на основе этих знаний? Kubernetes позволяет запускать команду оболочки, которая после успешного завершения завершается с 0, рассматривая это приложение как работоспособное. Для чтения MBeans мы можем использовать Jmxterm, который доступен для скачивания. Он может работать в неинтерактивном режиме, считывая определенный атрибут MBean - это как раз наш случай. Команда проверки работоспособности выглядит так:

Скрипт healthcheck.sh содержит одну команду:

У этого подхода есть недостатки: нам нужно предоставить jmxterm jar-файл, а также файл сценария в модуле Kubernetes. Давайте сначала попробуем избавиться от сценария.

3) Проверка работоспособности на основе JMX - 2-я попытка

Поскольку нам нужно знать только одну конкретную метрику, я написал специальное Java-приложение, которое можно скачать отсюда. Если значение атрибута count равно 1.0, генерируется исключение и завершается ненулевым кодом выхода.
Команда проверки работоспособности больше не является сложной, и ее можно ввести прямо в разделе command:

Тем не менее, файл jar должен быть частью модуля. Если вам это не нравится, давайте рассмотрим другое решение:

4) Человек не живет одной лишь проверкой здоровья

Не всегда может быть желательно уничтожить плохой модуль и запустить новый, если поток умирает. Это зависит от сбоя, с которым столкнулся поток. Вместо того, чтобы восстанавливать модуль автоматически, вы можете получить предупреждение о том, что приложение больше не работает, и исправить проблемы вручную перед повторным запуском приложения.

Kubernetes определяет довольно распространенный шаблон под названием sidecar. Вы создаете модуль, который состоит из основного контейнера, приложения Kafka Streams и дополнительного приложения, экспортера jmx. Официальные диаграммы управления, поставляемые Confluent, следуют этому стилю. Брокер Kafka, Schema Registry, Rest Proxy, KSQL - у всех них есть экспортер jmx на стороне. Просто взгляните на этот дескриптор развертывания, настраивающий контейнер prometheus-jmx-exporter на стороне основного контейнера, на котором запущен KSQL.

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

Однако наличие сопутствующего элемента означает, что нам необходимо предоставить дополнительные ресурсы и бюджет для дополнительного контейнера - по одному на каждое приложение Kafka Streams.

С помощью сопроводительного файла в нашем приложении Kafka Streams нам может больше не понадобиться проверка работоспособности. Преимущество использования только показателей и предупреждений и отказа от проверок работоспособности состоит в том, что мы не загромождаем контейнер приложения Kafka Streams дополнительными файлами jar.

В жизни не бывает бесплатных обедов! Нам нужно настроить систему мониторинга и оповещения, уведомляющие нас, когда приложение Kafka Streams умирает - нам нужно углубиться 🕳️.

Добавление контейнера с коляской

Во-первых, давайте настроим приложение Kafka Streams для запуска внутри контейнера докеров. Как уже упоминалось, нам также необходимо передать несколько com.sun.management.jmxremote аргументов JVM, чтобы предоставить JMX MBeans. Поскольку автоматизировать создание и публикацию образа докера - хорошая идея, давайте воспользуемся отличным плагином gradle и настроим образ докера и само приложение в файле build.gradle:

Обратите внимание - нет необходимости устанавливать свойство java.rmi.server.hostname, поскольку внутри модуля контейнеры совместно используют свои сетевые пространства имен и взаимодействуют друг с другом с помощью localhost. Это многое упрощает.

Пришло время для коляски jmx-экспортера. Ему нужен файл конфигурации. Хорошая практика - разделить приложение и его конфигурацию. В Kubernetes для этого есть специальный объект - ConfigMap:

Это очень простой пример - экспортер jmx подключается к приложению Kafka Streams через localhost порт 5555 и считывает все показатели. Важно использовать тот же порт, что и в основной конфигурации приложения.

Когда ConfigMap создается в Kubernetes, мы можем использовать его в deployment, подключив его как том:

Последний шаг - добавить контейнер sidecar в модуль:

и выставляем его с помощью Kubernetes Service:

Мы рекомендуем использовать Оператор Прометея внутри экземпляра Kubernetes. Затем вы можете настроить ServiceMonitor для автоматического добавления экспортера jmx в качестве цели для экземпляра Prometheus:

После того, как Prometheus прочитает метрики, мы можем создавать предупреждения и настраивать диспетчер предупреждений для отправки необходимых уведомлений, используя канал связи по вашему выбору: Slack или обмен текстовыми сообщениями кажется хорошей идеей.

Опять же, Оператор Прометея многое упрощает. Все, что нам нужно сделать, это создать объект Kubernetes вида PrometheusRule:

Поле expr определяет триггер предупреждения. В этом примере он сработает, если все показатели kafka_streams_kafka_metrics_count_count для всех заданий равны 1. Как упоминалось ранее, мы предполагаем, что в таком случае поток мертв.

Как уже было сказано, помимо предупреждений у нас есть метрики приложения Kafka Streams в Prometheus, и мы можем визуализировать их с помощью Grafana:

Ешь свой торт и тоже ешь

Имея и метрики, и проверку работоспособности, мы можем сохранить функции самовосстановления модуля Kubernetes и получать уведомления, если возобновление непрерывно не удается.

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

достаточно

Мониторинг приложений Kafka Streams оказался нетривиальным. Вам необходимо решить, удовлетворят ли просмотр показателей и, возможно, определение предупреждений вашим требованиям SLA. В некоторых случаях требуется перезапуск, выполняемый в автоматическом режиме, и именно здесь срабатывает функция livenessProbe. Наконец, сочетание обоих подходов должно обеспечить максимальную уверенность в отношении доступности и работоспособности вашего приложения.

Этот пост был написан вместе с Гжегожем Кодуром, нашим экспертом по Kubernetes в SoftwareMill.



Ищете экспертов по Scala и Java? Мы заставим технологии работать на ваш бизнес. Посмотреть проекты, которые мы успешно реализовали.