Перейти к содержимому
ГоМастер

Поиск по урокам

Найдите урок, курс, термин или раздел

Урок 3 из 25 ~18 мин +20 XP

Установка: kafka-go и локальный брокер

Установка kafka-go занимает одну команду, а вот локальный брокер — половину вечера, если идти без карты: advertised listeners, KRaft и флаги консольных утилит имеют свойство съедать время новичка. В этом уроке соберём рабочую среду целиком: go get для клиента, docker compose для брокера, первый топик через CreateTopics и консольную проверку, что сообщения ходят.

Содержание урока · 10 разделов

Kafka — единственный инструмент курса, который нельзя почувствовать в песочнице: клиент говорит по TCP с живым брокером, поэтому без окружения всё сведётся к чтению. Хорошая новость в том, что среда собирается один раз и живёт годами: библиотека подключается к проекту одной командой, а брокер — это один Docker-контейнер, который стартует за полминуты и не просит конфигов, если знать три переменные. В этом уроке пройдём весь путь от пустой папки до первого сообщения в собственном топике: go mod init и go get, docker-compose.yml с современным single-node брокером без ZooKeeper, создание топика из Go и из консоли, проверка продюсером и консьюмером. Каждая команда урока копируется как есть — к концу у вас будет ровно та площадка, на которой построены все двадцать пять уроков курса. Сверх этого ничего не понадобится: ни кластера, ни ZooKeeper, ни ручных конфигов — несколько переменных окружения закрывают весь KRaft-режим для одиночной ноды.

go get: установка kafka-go в проект#

Установка kafka-go выглядит стандартно для Go-модулей: создаём модуль командой go mod init и добавляем зависимость github.com/segmentio/kafka-go через go get — импорт-путь совпадает с репозиторием, никаких спецдвижений. Библиотека написана на чистом Go: внутри нет ни строчки cgo, поэтому сборка не требует GCC и системных заголовков, кросс-компиляция из macOS в Linux работает из коробки, а итоговый бинарник — обычный статичный файл, как у любого сервиса на стандартной библиотеке. Это не мелочь: альтернативный клиент confluent-kafka-go тянет за собой C-библиотеку librdkafka, и его сборка в Alpine-образе превращается в отдельный проект. Версия фиксируется в go.mod как обычно; библиотека живёт по классическому тегированию v1 и спокойно обновляется между минорами. Если рядом в проекте уже лежат модули из курсов по базовому Go, ничего перенастраивать не нужно — kafka-go встанет в тот же go.mod и тот же кэш модулей. Проверка сборки проста: импортируйте пакет в любой файл и выполните go build — компилятор подтянет модуль и честно покажет ошибку, если версия не сошлась. Всё это делает kafka-go особенно удобной для CI: сборка тестового образа не тянет ни C-инструментарий, ни системных зависимостей.

Три команды для нового проекта

GO
mkdir kafka-demo && cd kafka-demo

go mod init kafka-demo

go get github.com/segmentio/kafka-go

# проверить, что зависимость легла в go.mod
cat go.mod

go mod init создаёт модуль с именем kafka-demo, go get подтягивает последнюю версию библиотеки и пишет её в go.mod вместе с контрольными суммами в go.sum. Отдельного клиента ставить не нужно: kafka-go — единственная зависимость курса, без librdkafka и системных пакетов. Дальше импорт в коде выглядит как github.com/segmentio/kafka-go и сокращается до kafka.

Локальный брокер kafka в Docker Compose#

Современный Kafka не требует ZooKeeper: со версии 2.8 доступен режим KRaft, где кворум метаданных живёт внутри самих брокеров, а с третьей версии он стал основным путём. Для разработки берём single-node конфиг: один контейнер одновременно и брокер, и контроллер. Минимальный docker-compose.yml для образа bitnami/kafka выглядит так, как в блоке ниже, и в нём важно понимать три переменные. PROCESS_ROLES и CONTROLLER_QUORUM_VOTERS включают KRaft-режим для одиночного узла. LISTENERS описывает, на каких портах брокер принимает соединения: 9092 — клиентский, 9093 — внутренний для контроллера. А ADVERTISED_LISTENERS — адрес, который брокер сообщает клиентам в ответе «я здесь»: если написать там имя контейнера, ваш Go-код с хоста получит недостижимый адрес — классическая ловушка, ниже отдельный коллаут. Тома наружу выносим и порт 9092; данные живут в именованном томе kafka_data, поэтому рестарты и пересоздание контейнера учебный топик не стирают. Файл целиком копируется в проект без правок: все переменные обязательны, и их сокращение — самый быстрый способ получить брокер, который поднимается, но не отвечает.

docker-compose.yml одного брокера

GO
services:
  kafka:
    image: bitnami/kafka:3.7
    container_name: kafka
    ports:
      - "9092:9092"
    environment:
      - KAFKA_CFG_NODE_ID=0
      - KAFKA_CFG_PROCESS_ROLES=controller,broker
      - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093
      - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092
      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9093
    volumes:
      - kafka_data:/bitnami/kafka

volumes:
  kafka_data:

Одна услуга, один образ, шесть переменных: KRaft-режим без ZooKeeper, клиентский слушатель на 9092, контроллерный на 9093. Advertised-адрес localhost:9092 — то, что брокер скажет вашему Go-коду с хоста, поэтому он отличается от внутреннего адреса слушателя. Именованный том kafka_data держит данные лога между рестартами: без него пересоздание контейнера стирает все топики.

Первый топик: kafka.Client и консоль#

Топик в Kafka не создаётся автоматически первой записью — по умолчанию брокер отвечает ошибкой на запись в несуществующий канал, и это осознанная защита от опечаток. Создать топик можно двумя путями. Первый — консольная утилита kafka-topics.sh внутри контейнера: она нужна один раз, чтобы поднять топик orders с тремя партициями и фактором репликации 1. Второй — из кода, и это то, что делают сервисы при старте: kafka-go открывает Admin API через структуру kafka.Client с адресом кластера в поле Addr, а создание топиков — её метод CreateTopics. Он принимает контекст и CreateTopicsRequest со срезом TopicConfig; в каждом конфиге важны три поля: имя, NumPartitions и ReplicationFactor — для локального брокера реплика всегда одна, потому что брокер один. Полное управление топиками из Go — конфиги, изменение числа партиций, удаление — отдельный урок про Admin API, а здесь Client.CreateTopics выполняет роль init-миграции: сервис стартует, гарантирует нужный топик и работает дальше. В командной работе создание топиков обычно выносят в скрипт деплоя, чтобы код и инфраструктура не спорили, кто автор канала. В учебном проекте проще держать клиента и запрос в main.go перед стартом продюсера: против чистого брокера сервис сам себя готовит, а против уже настроенного просто повторяет знание о топике.

Создание топика из Go

GO
client := &kafka.Client{Addr: kafka.TCP("localhost:9092")}

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

res, err := client.CreateTopics(ctx, &kafka.CreateTopicsRequest{
        Topics: []kafka.TopicConfig{
                {
                        Topic:             "orders",
                        NumPartitions:     3,
                        ReplicationFactor: 1,
                },
        },
})
if err != nil {
        log.Fatal(err)
}

for topic, terr := range res.Errors {
        fmt.Println(topic, terr)
}

kafka.Client — вход в Admin API: структура с адресом кластера и Transport'ом по умолчанию, потокобезопасная и долгоживущая. Метод CreateTopics принимает CreateTopicsRequest со срезом TopicConfig и возвращает ответ: err означает сбой запроса целиком, а судьба каждого топика приходит в карте Errors. Для существующего топика там лежит TopicAlreadyExists — её отфильтровывают через errors.Is, свежесозданный топик даёт nil. kafka.TCP превращает строку адреса в net.Addr.

Чек-лист рабочей среды#

  • go mod init и go get выполнены, kafka-go видна в go.mod.
  • docker compose up -d прошёл, контейнер kafka отвечает на docker ps со статусом Up.
  • ADVERTISED_LISTENERS указывает на localhost:9092 — иначе Go-код не дозвонится с хоста.
  • Топик orders создан с тремя партициями и виден в списке kafka-topics.sh --list.
  • Данные лежат в именованном томе kafka_data, а не в файловой системе контейнера.
  • Порт 9092 свободен на хосте: локальный конфликт портов — второй по частоте сюрприз после advertised listeners.

Проверка связи: консольные продюсер и консьюмер#

Прежде чем писать Go-код, стоит убедиться, что канал жив, — и для этого в образе есть консольные утилиты, которые сами же и пригодятся при отладке весь курс. kafka-console-producer.sh читает строки из стандартного ввода и отправляет каждую как сообщение: набрали текст, нажали Enter — уехало. kafka-console-consumer.sh с флагом --from-beginning вычитывает топик с самого старого живого оффсета и печатает сообщения в терминал, оставаясь висеть и показывать новые. Запустив оба в двух терминалах, вы увидите круговорот: строка ушла из продюсера — появилась у консьюмера. Эта пара — быстрее любой диагностики: если консольные утилиты внутри контейнера ходят, а Go-код нет, проблема в адресе с хоста, то есть в advertised listeners; если и консоль молчит, смотрите, жив ли контейнер и существует ли топик. Утилиты принимают те же --bootstrap-server, что и клиент: единственная точка правды — адрес брокера. Оба инструмента живут в том же образе, что и брокер, поэтому работают даже там, где нет ни Go, ни вашего кода: удобно проверять окружение до репродукции бага. Если консьюмер печатает ваши строки — канал исправен, и любую следующую проблему стоит искать в коде, а не в окружении.

Команды урока одним столом#

ДействиеКоманда
Поднять брокерdocker compose up -d
Статус окруженияdocker compose ps
Создать топикdocker exec kafka kafka-topics.sh --create --bootstrap-server localhost:9092 --topic orders --partitions 3
Список топиковdocker exec kafka kafka-topics.sh --bootstrap-server localhost:9092 --list
Прочитать топик с началаdocker exec kafka kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic orders --from-beginning
Полный сброс с даннымиdocker compose down -v

Почему держать брокер под рукой до конца курса#

Код этого курса — сетевой по определению, и честная оговорка будет звучать одинаково в каждом уроке: песочница сайта не умеет сеть и TCP-сокеты, поэтому kafka-код запускается локально против брокера в Docker, а интерактивы песочницы показывают тематические программы на чистом Go, обычно эмулирующие нужную механику — от хэша ключа до батчей. Такой формат не потеря: механики партиционирования и адресации удобнее щупать интерактивами, а ход сообщений в живом брокере — это десять минут подъёма окружения один раз. С этого урока у вас есть всё: клиент в go.mod, брокер на localhost:9092, топик с тремя партициями и утилиты, чтобы заглянуть внутрь в любую секунду. Дальше каждый урок будет давать код, который стоит против этой площадки: скопировали — запустили — увидели своими глазами. Именно на этом цикле Kafka перестаёт быть набором терминов и становится инструментом, который вы читаете и отлаживаете без страха. К этому же уроку стоит вернуться при смене машины: чек-лист выше — самодостаточная инструкция восстановления окружения за пять минут.

Проверка: адрес, который видит клиент

Go-код на хосте соединяется с брокером, но запись висит. Внутри контейнера утилиты работают. Первое, что проверяем?

Проверка: что делает go get

Что происходит после go get github.com/segmentio/kafka-go?

Что станет с топиком после рестарта?

Прочитайте код и выберите, что он выведет:

# в compose объявлен именованный том:
# volumes: kafka_data:/bitnami/kafka

docker compose down
docker compose up -d

docker exec kafka kafka-topics.sh \
  --bootstrap-server localhost:9092 --list

Соберите создание топика

Допишите вход в Admin API, сборку адреса и вызов создания топика.

client := &kafka.{ Addr: kafka.("localhost:9092"), } res, err := client.(ctx, &kafka.CreateTopicsRequest{ Topics: []kafka.TopicConfig{ { Topic: "orders", NumPartitions: 3, ReplicationFactor: 1, }, }, })

Соберите путь до первого сообщения

Расставьте шаги от пустой папки до записи: модуль, зависимость, брокер, топик, Writer, отправка, закрытие.

Строки

Ваша программа

Нажимайте на строки слева, чтобы собрать программу

Карточки: установка и окружение

Термин

go.mod и go.sum

нажмите, чтобы перевернуть
Определение

Манифест зависимостей модуля и файл контрольных сумм. kafka-go попадает туда через go get github.com/segmentio/kafka-go.

1 / 6

Среда готова: клиент в go.mod, брокер на localhost:9092, топик orders с тремя партициями, консольные утилиты под рукой. Дальше по курсу: в уроке про Writer напишем первого продюсера и разберём WriteMessages с контекстом и ошибками; в уроке про Reader — первого консьюмера. Создание топиков из кода вернётся с полным Admin API в уроке шестнадцатом. Домашнее задание — собрать всё из урока руками: эта площадка будет колесом всей телеги, и час, вложенный сейчас, вернётся на каждом следующем уроке. Если что-то не взлетело — начните с коллаута про advertised listeners: девять из десяти проблем подключения живут именно там.

Песочница урока

Редактируйте код и запускайте его прямо здесь — интерпретатор работает в браузере, ничего устанавливать не нужно. За каждый запуск — +2 XP.

Вывод

Запустите код, чтобы увидеть вывод.

Коротко: что запомнить

  • kafka-go ставится через go get как обычная зависимость: чистый Go, без cgo и системных пакетов.
  • Локальный брокер — один контейнер bitnami/kafka в режиме KRaft: без ZooKeeper, с томом для данных.
  • Advertised listeners обязаны указывать на адрес, достижимый с хоста: localhost:9092 — для локальной разработки.
  • Топики создаются явно: kafka.CreateTopics из кода или kafka-topics.sh из консоли.
  • Консольные продюсер и консьюмер — быстрая диагностика: если консоль ходит, а Go нет, проблема в адресе с хоста.
  • Kafka без ZooKeeper — это KRaft: single-node из шести переменных окружения поднимается за полминуты.
  • down сохраняет том, down -v стирает всё: разница между рестартом окружения и полным сбросом.
  • Песочница сеть не поднимает: kafka-код — локальный Go и брокер в Docker, интерактивы — программы на чистом Go.

Домашнее задание

Соберите среду по уроку и зафиксируйте её в репозитории проекта: docker-compose.yml из урока, скрипт setup.sh с go mod init, go get и созданием топика orders на три партиции. Проверьте полный цикл: compose up, CreateTopics через go run, отправка сообщения Writer'ом из четвёртого урока-тизера, чтение через kafka-console-consumer. Затем выполните docker compose down -v и прогоните скрипт заново — окружение должно восстанавливаться с нуля без ручных шагов. Сохраните compose и скрипт в репозитории: они пригодятся и при смене машины, и при переходе на новые версии брокера.

Личные заметкиПусто
Хранятся только в вашем браузере (Kafka · Установка: kafka-go и локальный брокер)

Вопросы и ответы по уроку

Можно ли ставить Kafka без Docker?

Можно: скачать архив с сайта Apache, распаковать и запустить bin/kafka-server-start.sh с KRaft-конфигом из папки config/kraft. Но Java-окружение, ручные конфиги и очистка логов руками делают Docker-путь практичнее для разработки: контейнер поднимается одной командой и стирается одной командой.

Почему образ bitnami, а не Apache и не Confluent?

Все три рабочие. Bitnami даёт KRaft single-node в шести переменных окружения без ZooKeeper-контейнера, Confluent требует либо пару контейнеров, либо больше переменных, а чистый Apache — ручную правку конфигов. Для учёбы важна простота подъёма, а не производительностные флаги, поэтому курс держится bitnami; конфиги переносимы — все настройки из урока переезжают на любой образ с минимальными правками имён переменных.

Нужен ли ZooKeeper для учёбы?

Нет. Начиная с Kafka 3.x режим KRaft — штатный путь, и single-node из урока работает на нём. Отдельный контейнер ZooKeeper нужен только старым версиям 2.x и специфическим кластерным конфигурациям; для локальной разработки и этого курса он не требуется. Практический совет: какую бы сборку вы ни выбрали, убедитесь, что её версия поддерживает KRaft — 3.x и новее.

Термины урока

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

Следующая ступень учебного пути

Ebitengine25 уроков~12 чпрактика25 уроков уже доступны

Ebitengine: 2D-игры на Go

Курс Ebitengine для Go: игровой цикл Update/Draw, спрайты и анимации, ввод, коллизии, тайлмапы, камера, звук, сцены и сборка на платформы. 25 уроков.

  • Понимать игровой цикл Update/Draw и Layout
  • Рисовать спрайты, атласы и примитивы
  • Обрабатывать ввод: клавиатура, мышь, тач
  • Строить движение, коллизии и анимации