Найти в Дзене
Я, Golang-инженер

#81. Kafka в Go: азы для старта работы с брокером сообщений

Это статья об основах программирования на Go. На канале я рассказываю об опыте перехода в IT с нуля, структурирую информацию и делюсь мнением. Хой, джедаи и амазонки! В публикации будет необходимый и достаточный объём информации, чтобы начать применять брокер сообщений Kafka в своих проектах на Go. В первой части публикации напишем два простых приложения на Go, которые будут общаться через Apache Kafka. Во второй части обзорно рассмотрим историю Kafka и как её простым способом развернуть на своём ПК. В конце ссылка на GitHub. Расскажу историю. Году в 2000-м, когда мне было около десяти лет, к нам приехали погостить родственники из-за границы. Когда уезжали, написали свой e-mail. У меня тогда и компа не было, не то что интернета; и для меня было загадкой: что если им отправить письмо, а у них в это время будет выключен компьютер? Письмо потеряется, думал я. Но конечно электронные письма не теряются из-за выключенного компьютера получателя. Kafka, как и другие брокеры сообщений, могут б
Оглавление

Это статья об основах программирования на Go. На канале я рассказываю об опыте перехода в IT с нуля, структурирую информацию и делюсь мнением.

Хой, джедаи и амазонки!

В публикации будет необходимый и достаточный объём информации, чтобы начать применять брокер сообщений Kafka в своих проектах на Go.

В первой части публикации напишем два простых приложения на Go, которые будут общаться через Apache Kafka. Во второй части обзорно рассмотрим историю Kafka и как её простым способом развернуть на своём ПК.

В конце ссылка на GitHub.

1. Пишем ПО на Golang с применением Apache Kafka

1.1. Кратко о брокерах сообщений

Расскажу историю.

Году в 2000-м, когда мне было около десяти лет, к нам приехали погостить родственники из-за границы. Когда уезжали, написали свой e-mail. У меня тогда и компа не было, не то что интернета; и для меня было загадкой: что если им отправить письмо, а у них в это время будет выключен компьютер? Письмо потеряется, думал я. Но конечно электронные письма не теряются из-за выключенного компьютера получателя.

Kafka, как и другие брокеры сообщений, могут быть полезны в т.ч. в таких же сценариях: когда один сервис отдаёт данные, а другой обязательно должен их получить, но временно недоступен. Данные с Kafka (при штатной работе) не потеряются.

Вольное определение брокера сообщений:

Брокер сообщений - это асинхронная почтовая программа обмена данными между другими программами.

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

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

1.2. Пишем микросервисы на Go

Для наглядности я написал два простых микросервиса, которые будут обмениваться данными через Кафку. Каждый микросервис - это один файл по ~50 строк кода. Вот структура всего проекта:

Структура проекта
Структура проекта

Consumer и producer - это мои микросервисы; producer создаёт данные и отправляет их в Кафку, а consumer читает данные из Кафки и выводит их в терминал. Всё.

Для работы с Kafka в Go использовал простую библиотеку github.com/segmentio/kafka-go.

Первый микросервис:

Код микросервиса producer
Код микросервиса producer

Второй микросервис:

Код микросервиса consumer
Код микросервиса consumer

Чтобы микросервисы заработали, нужно поднять у себя в окружении Кафку. Об этом в следующем параграфе.

Пример работы микросервиса producer (с работающей Кафкой):

Терминал для работы с producer
Терминал для работы с producer

Для удобства, я создал отдельный терминал для микросервиса consumer, т.к. он читает данные в бесконечном цикле и штатно не прекратит работать:

Терминал для работы с consumer
Терминал для работы с consumer

В общем, Кафка работает: один микросервис отдаёт данные в Кафку, другой данные запрашивает с некоторой задержкой.

Чтобы это стало возможным, нужно запустить Kafka-окружение на компьютере. Проще всего это сделать через Docker Compose, что я и сделал.

2. Apache Kafka

2.1. Как появилась Apache Kafka

Не нашёл систематизированной информации о том, каким был первый брокер и как эволюционировала идея передачи данных между компонентами ПО.

Есть любопытная презентация 2017 г. на эту тему, можете посмотреть для ознакомления. Ниже скриншот из неё:

Слайд презентации, ссылка выше
Слайд презентации, ссылка выше

Разберём фразу "брокер сообщений". Сообщение - это обобщённый термин, в широком смысле это может быть файл, может быть строка текста или другие данные. Брокер - это просто посредник. Брокер сообщений для большей ясности можно трактовать "Посредник передачи данных".

ПО для обмена данными наверняка развивалось одновременно с развитием сетей и архитектуры ЦП. Но именно как брокер сообщений, первым ПО можно считать IBM MQ, изданное в 1992 г. компанией IBM. MQ - аббревиатура для message queue, т.е. очередь сообщений. Это ПО реализовало концепцию MOM - message-oriented middleware, т.е. концепцию обмена данными между частями общей системы (общего ПО).

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

Всего брокеров или ПО с функционалом брокеров под 40 штук согласно Wikipedia. Kafka - один из самых популярных.

Кафку разработала компания LinkedIn для внутренних целей, основными авторами были три программиста: Джун Рао (в других переводах Цзюнь Жао), Джей Крепс и Ния Нархид (на момент разработки Кафки ей примерно 26 лет).

Наименование ПО дано Крепсом в честь писателя Франца Кафки. Новое ПО предназначено для работы с огромным объёмом бесконечно поступающей информации, а стиль повествования Франца Кафки похож на это.

Вот что пишет Анатолий Рясов, писатель, о творчестве своего коллеги по цеху Франца Кафки:

...На первый взгляд, в манере письма Кафки вообще нет ничего особенно примечательного, но описать ее оказывается не так-то просто, ведь ясной эта речь может показаться лишь тому, кто не совершает ни малейшего усилия в нее вникнуть...
... Эта речь зачастую строится следующим образом: дается некое утверждение, от которого сразу же ответвляются еще несколько утверждений, на начальном этапе являющихся чем-то вроде уточнений или трактовок первого (едва ли здесь уместно определение основного) утверждения. В дальнейшем эти трактовки начинают претендовать на самостоятельность, и действительно становятся полноценными утверждениями, а не просто толкованиями, и потому по примеру первого тезиса порождают собственные комментарии и оговорки, и так - до бесконечности...

Возвращаемся к ПО. В 2011 г. разработчики ПО Kafka открыли исходный код под лицензией Apache, проект был принят в инкубатор фонда Apache Software Foundation, а в 2012 г. стал проектом верхнего уровня этого фонда.

К слову, в 2017 г. Mit Technology Review включил Нию Нархид в список новаторов в возрасте до 35 лет. В следующем году Нархеде вошла в список 50 лучших женщин в сфере технологий в Америке и мире по версии Forbes.

Ния Нархид на конференции dotScale-2017 - одна из основных разработчиков Apache Kafka: фото - Wikipedia
Ния Нархид на конференции dotScale-2017 - одна из основных разработчиков Apache Kafka: фото - Wikipedia

Так выглядит архитектура Apache Kafka:

Архитектура Apache Kafka - фото Wikipedia
Архитектура Apache Kafka - фото Wikipedia

Есть небольшой курс за символическую плату на Stepik: "Брокеры сообщений. Apache Kafka", - курс совсем небольшой, но какие-то знания об устройстве Кафки получить можно. Курс я прошёл:

Фрагмент сертификата
Фрагмент сертификата

Итак, некоторые знания об истоках появления Kafka имеем; идём дальше - как запустить Кафку на компьютере?

2.2. Как поднять Кафку на компьютере?

2.2.1. Docker-compose файл

Создадим файл docker-compose.yml:

Описание использование образа для Кафки
Описание использование образа для Кафки

Проверить, не используются ли у вас порты, которые прописываются в compose-файле можно командой:

sudo lsof -i :2181

где 2181 - пример номера порта, планируемого к используемому. Если в терминале информация, что порт используется - нужно выбрать другой порт для compose-файла.

Напомню, что порт - это числовой идентификатор, который используется для маршрутизации сетевых данных на компьютере к нужному процессу (приложению).

Пару слов о содержимом докер-компоуз файла. В нём описано создание двух сервисов: ZooKeeper и Kafka, а также пользовательскую сеть к которой эти сервисы подключены (докер по-умолчанию создаёт сеть для связи описанных в файле сервисов с каким-то своим именем, но я захотел назначить явное имя для учебной сети).

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

Подробнее о переходе от Zookeeper к KRaft можно почитать в статье 2024 г. From ZooKeeper to KRaft: How the Kafka migration works.

Итак, файл сохранили, запускаем контейнеры командой:

docker compose up -d
Терминал
Терминал

Далее нужно создать топик внутри контейнера Кафки.

2.2.2. Создаём топик Кафки

Топик в Apache Kafka - это имя объекта, в котором хранятся сообщения. Кафка помещает в топик сообщения от продьюсера, а консьюмер опрашивает топик Кафка для получения сообщений.

Для создания топика в Кафке можно воспользоваться консольной командой:

docker exec kafka-broker-sandbox-container kafka-topics --bootstrap-server kafka-broker-sandbox:29092 --create --topic my-learning-topic --partitions 1 --replication-factor 1

Результатом должно быть сообщение

Created topic my-learning-topic.
Терминал
Терминал

Разберём детали команды:

  • docker exec kafka-broker-sandbox-container: выполняет команду внутри контейнера с именем kafka-broker-sandbox-container (имя контейнера Кафки определено в докер-компоуз файле);
  • kafka-topics: утилита Kafka для управления топиками (внутри контейнера);
  • --bootstrap-server kafka-broker-sandbox:29092: флаг (команда) и значение для этого флага - адрес Kafka брокера для подключения. kafka-broker-sandbox - это имя сервиса, которое Docker преобразует во внутренний IP-адрес, а 29092 - это внутренний порт, который Kafka слушает;
  • --create: флаг для создания топика;
  • --topic my-learning-topic: флаг имени создаваемого топика и значение флага, значение будет фигурировать в коде микросервисов;
  • --partitions 1: количество партиций. Это разделы внутри топика, где каждая партиция - отдельная очередь сообщений.
  • --replication-factor 1: фактор репликации (количество копий топика, включая исходный экземпляр).

В общем, всё - можно запускать микросервис и тестировать работу.

2.2.3. Библиотеки Go для Apache Kafka

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

Библиотека для взаимодействия с Кафкой в go которую я использовал - github.com/segmentio/kafka-go - считается простой в применении.

Для более детальной настройки и для высоконагруженных приложений может быть полезна другая библиотека - github.com/twmb/franz-go/pkg/kgo.

Рассмотрим фрагмент кода продьюсера:

Код продьюсера
Код продьюсера

Здесь я использовал только две настройки в структуре WriteConfig для отправки сообщений: имя топика (задан командой через флаг при создании топика в Кафке) и url куда отправлять сообщения (описан в докер-компоуз файле Кафки).

В действительности в передаваемой в функцию NewWriter структуре WriterConfig много настроек, в т.ч. часть полей - тоже структуры:

Код библиотеки go для взаимодействия продьюсера с Кафкой
Код библиотеки go для взаимодействия продьюсера с Кафкой

С микросервисом-консьюмером также - возможных настроек много, на практике чтобы просто заработало - используем минимум настроек:

Код консьмера
Код консьмера

Вот как выглядит часть структуры ReaderConfig для консьюмера:

Фрагмент go-библиотеки для взаимодействия консьюмера с Кафкой
Фрагмент go-библиотеки для взаимодействия консьюмера с Кафкой

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

3. Итоги

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

Пример, что я показал в публикации, по-смыслу мне напоминает первый код на go "Hello, go-developers", только в отношении Кафки. В плане, что всё упрощено - но уже работает.

Безусловно, это первые шаги в изучении брокеров, но если Кафка ранее была не то что тёмным лесом, а Лихолесьем с пауками из книги Хоббит Толкиена, то сейчас это освещённая тропинка в берёзовой роще.

В публикации мы познакомились с основными терминами:

  • Брокер сообщений - общее название семейства ПО, таких как Apache Kafka;
  • Сообщения - данные, пересылаемые одним ПО в другое ПО;
  • Producer - сервис, который отправляет сообщения в Кафку;
  • Consumer - сервис, который опрашивает Кафку о новых сообщениях;
  • Топик - хранилище Кафки;
  • Партиция - раздел топика, в котором хранятся сообщения.

С кодом, рассмотренном в этой публикации, можно ознакомиться на GitHub. Следующим шагом на пути прарктики Apache Kafka может быть более тонкая настройка и добавление нескольких консьюмеров. А также передача не строки в Кафку, а использовать gRPC-протокол для компактной передачи данных.

На этом у меня всё, благодарю за внимание. А также успехов в труде и отдыхе.

https://ru.freepik.com
https://ru.freepik.com

Бро, ты уже здесь? 👉 Подпишись на канал для начинающих IT-специалистов «Войти в IT» в Telegram, будем изучать IT вместе 👨‍💻👩‍💻👨‍💻