Друзья, привет. В статье я расскажу как собрать решение для быстрого старта вашей разработки из standalone Java приложения, брокера и Zookeeper’а Kafka, поднятых в отдельных Docker контейнерах и настроенной plaintext авторизацией для доступа как с локальной машины, так и из внешнего контура.
Готовый проект на github можно забрать в конце статьи
Для начала придется определиться с вендором образа Apache Kafka для нашего контейнера. Требования каждого конкретного проекта разнятся по необходимому уровню безопасности и надежности решения, в некоторых случаях конечно придется собирать свой собственный образ, но для большинства проектов будет разумным выбрать один из доступных на docker hub. На 2020й год есть три основных популярных вендора образов kafka+zookeper:
Для запуска и конфигурирования образов используется docker-compose, который позволяет легко запускать мультиконтейнерные приложения. Без него не обойтись, потому что минимальная конфигурация kafka предусматривает связку из zookeeper и хотя бы одного брокера.
Сompose идет в комплекте с mac/windows — дистрибутивом Docker, так что установка необходимого окружения сводится к загрузке и установке дистрибутива с docs.docker.com/engine/install.
А вот linux пользователям его необходимо устанавливать отдельно. За гайдом по установке docker + compose лучше всего обратиться к официальной документации docs.docker.com/compose/install.
Общая схема нашей конфигурации для всех клиентов и контейнеров будет следующей:
К одному координатору будет подключаться один брокер с открытыми портами 9093 — для localhost подключений и 9092 для подключений с других машин.
Для доступа из внешних сетей включим авторизацию через логин пароль без ssl шифрования. Для работы через ssl необходимо выпускать собственные ключи и подписывать сертификаты, весь процесс хорошо расписан в официальной документации.
В итоге файл будет иметь следующий вид(адрес нужно заменить на ваш публичный IP для возможности доступа из других сетей):
Для того что бы включить авторизацию необходимо передать kafka_server_jaas.conf файл в kafka. В папке с compose yaml файлом создадим kafka_server_jaas.conf и в нем добавим одного пользователя admin с паролем admin-secret:
Этот файл будет передаваться в образ с kafka брокером через:
В итоге мы должны получить 2 файла, которые находятся в одной директории:
В этой директории нужно вызвать команду:
флаг -d позволяет запуститься в Detached mode и закрыть консоль при необходимости без выключения образов.
Напишем минималистичный клиент с возможностью публикации и чтения сообщений из kafka. Для этого создадим новый проект через Spring Initializr или любой другой привычный вам инструмент. Будет достаточно подключить одну зависимость:
Настройку Spring Boot приложения я предпочитаю по возможности реализовывать через конфигурационные yaml файлы с минимальной конфигурацией в Java коде. За счет встроенного структурирования в Yaml-формат, эти файлы гораздо удобнее для человеческого восприятия, чем .properties файлы и позволяют группировать настройки по модулям. Единственный недостаток .yml конфигурации в том, что она не поддерживается в тестах, но он легко обходится встроенными инструментами boot’а.
В resources проекта создадим файл application.yml cо следующим содержанием:
Этот сетап работает для последовательной вычитки по одному сообщению (max-poll-records: 1) одним слушателем (concurrency: 1) и требует ручного подтверждения обработки сообщения в listener (ack-mode: manual_immediate).
Слушатель получает сообщение и логирует все доступные сведения о нем в консоль и комитит факт считывания.
Voilà! и приложение готово к запуску. Можно запускать dev вариант с локальным клиентом и локальной kafka, а так же к kafka можно получить доступ из других сетей если открыть 9092 порт и указать в application.yml адрес хоста.
Удачи в разработке! Весь код доступен в репозитории — github.com/layonez/kafka-example
Готовый проект на github можно забрать в конце статьи
Выбор docker образа Apache Kafka + Zookeeper
Для начала придется определиться с вендором образа Apache Kafka для нашего контейнера. Требования каждого конкретного проекта разнятся по необходимому уровню безопасности и надежности решения, в некоторых случаях конечно придется собирать свой собственный образ, но для большинства проектов будет разумным выбрать один из доступных на docker hub. На 2020й год есть три основных популярных вендора образов kafka+zookeper:
- oбразы от confluent [ субъективно, большой плюс — поставляются разработчиками самой Apache Kafka и наиболее надежны в плане информационной безопасности ]
- образы от bitnami [плюс, в сравнении с confluent, в том что образы нуждаются в минимальной конфигурации и “стартуют из коробки”]
- образы от wurstmeister [в этом примере я буду использовать их, потому что у проекта наибольшее активное комьюнити на github и hub.docker, а так же отличная документация ]
Установка Docker-compose
Для запуска и конфигурирования образов используется docker-compose, который позволяет легко запускать мультиконтейнерные приложения. Без него не обойтись, потому что минимальная конфигурация kafka предусматривает связку из zookeeper и хотя бы одного брокера.
Сompose идет в комплекте с mac/windows — дистрибутивом Docker, так что установка необходимого окружения сводится к загрузке и установке дистрибутива с docs.docker.com/engine/install.
А вот linux пользователям его необходимо устанавливать отдельно. За гайдом по установке docker + compose лучше всего обратиться к официальной документации docs.docker.com/compose/install.
Пишем yaml файл для compose
Общая схема нашей конфигурации для всех клиентов и контейнеров будет следующей:
К одному координатору будет подключаться один брокер с открытыми портами 9093 — для localhost подключений и 9092 для подключений с других машин.
Для доступа из внешних сетей включим авторизацию через логин пароль без ssl шифрования. Для работы через ssl необходимо выпускать собственные ключи и подписывать сертификаты, весь процесс хорошо расписан в официальной документации.
В итоге файл будет иметь следующий вид(адрес нужно заменить на ваш публичный IP для возможности доступа из других сетей):
Авторизация клиентов
Для того что бы включить авторизацию необходимо передать kafka_server_jaas.conf файл в kafka. В папке с compose yaml файлом создадим kafka_server_jaas.conf и в нем добавим одного пользователя admin с паролем admin-secret:
Этот файл будет передаваться в образ с kafka брокером через:
- указание пути к файлу в непосредственно конфиге kafka
KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf"
- маппинг локальной директории с файлом в /etc/kafka директорию образа
volumes:
- ./:/etc/kafka
Запуск контейнеров
В итоге мы должны получить 2 файла, которые находятся в одной директории:
- docker-compose.yml
- kafka_server_jaas.conf
В этой директории нужно вызвать команду:
$ docker-compose up -d
флаг -d позволяет запуститься в Detached mode и закрыть консоль при необходимости без выключения образов.
Java клиент на Spring Boot
Напишем минималистичный клиент с возможностью публикации и чтения сообщений из kafka. Для этого создадим новый проект через Spring Initializr или любой другой привычный вам инструмент. Будет достаточно подключить одну зависимость:
Настройку Spring Boot приложения я предпочитаю по возможности реализовывать через конфигурационные yaml файлы с минимальной конфигурацией в Java коде. За счет встроенного структурирования в Yaml-формат, эти файлы гораздо удобнее для человеческого восприятия, чем .properties файлы и позволяют группировать настройки по модулям. Единственный недостаток .yml конфигурации в том, что она не поддерживается в тестах, но он легко обходится встроенными инструментами boot’а.
Очень рекомендую попробовать посмотреть как изменится ваше восприятие старого .properties файла (особенно для больших проектов), если его переписать в yaml. Это можно сделать в пару кликов на www.toyaml.com/index.html.
В resources проекта создадим файл application.yml cо следующим содержанием:
Этот сетап работает для последовательной вычитки по одному сообщению (max-poll-records: 1) одним слушателем (concurrency: 1) и требует ручного подтверждения обработки сообщения в listener (ack-mode: manual_immediate).
Добавим классы producer и consumer
Слушатель получает сообщение и логирует все доступные сведения о нем в консоль и комитит факт считывания.
Запустим добавление сообщений в очередь каждые 3 секунды
для включения шедулера надо повесить аннотацию @EnableScheduling на наше spring приложение
Voilà! и приложение готово к запуску. Можно запускать dev вариант с локальным клиентом и локальной kafka, а так же к kafka можно получить доступ из других сетей если открыть 9092 порт и указать в application.yml адрес хоста.
Удачи в разработке! Весь код доступен в репозитории — github.com/layonez/kafka-example