Содержание урока · 10 разделов
- Установка rabbitmq: Docker одной командой
- Порты и команды после docker run
- Чек-лист живого брокера
- Management UI: обзор вкладок
- Пользователи и vhost: guest только для localhost
- Гонка старта: compose up, а брокера ещё нет
- Обновление брокера: volume и мажорные версии
- Песочница урока
- Коротко: что запомнить
- Вопросы и ответы
Код из первого урока честно отработал: amqp.Dial вернул connection refused, потому что стучался в порт, где никого нет. Брокер — отдельный процесс со своей памятью и диском, и его нужно сначала поднять. Родная установка через пакеты существует, но в разработке стандарт — Docker: версия брокера зафиксирована в compose-файле, окружение не замусоривается, а переезд на сервер выглядит как перенос того же yaml. Заодно с брокером мы получим management UI — веб-панель, в которой видно очереди, соединения и потребителей; без неё отладка превращается в слепое чтение логов. В этом уроке поднимем контейнер, осмотрим панель по вкладкам, разберём пользователей и vhost, а в конце напишем на Go проверку готовности, которую затем переиспользуют и тесты, и docker-compose. Терминал держите под рукой: весь урок про команды и их последствия. Команды ниже стоит не читать, а набирать — разница между «понял» и «умею» здесь ровно одна строка в истории терминала.
Установка rabbitmq: Docker одной командой#
Установка rabbitmq сводится к одной строке: docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:4-management. Разберём по частям. Флаг -d пускает контейнер в фоне, --name даёт ему внятное имя вместо случайного хэша. Флаг -p публикует порты: 5672 — протокол AMQP, по нему будут говорить ваши Go-сервисы; 15672 — HTTP-панель management UI для браузера. Образ rabbitmq:4-management — это брокер плюс панель; тег без management тоже существует, но панель в нём выключена, так что для обучения берите именно management. Мажорная версия в теге — страховка: без неё docker run однажды молча скачает свежий образ с другим поведением, и вы будете искать баг в коде, а виноват окажется брокер. Тот же перевод в docker-compose: два порта в ports, образ и имя в соответствующих полях. В разговорах про установку rabbitmq docker упоминают всегда — контейнер даёт предсказуемую версию брокера за минуту, а не спор о способе развёртывания.
Порты и команды после docker run#
| Порт или команда | Что это | Когда понадобится |
|---|---|---|
| 5672/tcp | протокол AMQP 0-9-1: порт, на который смотрит amqp.Dial | каждый Go-клиент курса |
| 15672/tcp | management UI и его HTTP API | диагностика очередей и потребителей |
| 5671/tcp | AMQP поверх TLS | продакшен и amqps |
| docker logs rabbitmq | логи брокера: старт, handshake, ошибки | когда клиент не подключается |
| docker exec rabbitmq rabbitmqctl status | состояние брокера изнутри контейнера | UI недоступен, нужна правда |
| -v rabbitmq-data:/var/lib/rabbitmq | именованный volume с данными | пережить recreate контейнера |
Проверяем брокер из Go, не устанавливая клиента
GOpackage main
import (
"fmt"
"log"
"net/http"
)
func main() {
req, err := http.NewRequest(http.MethodGet,
"http://localhost:15672/api/overview", nil)
if err != nil {
log.Fatal(err)
}
req.SetBasicAuth("guest", "guest")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
fmt.Println("статус:", resp.StatusCode) // 200 — брокер жив
}До установки amqp091-go брокер проверяется стандартной библиотекой: management UI публикует HTTP API на том же порту 15672, и запрос /api/overview с basic-авторизацией возвращает JSON со статистикой брокера. Статус 200 — брокер жив и порт проброшен; 401 — контейнер отвечает, но логин не подошёл; ошибка соединения — вы стучитесь не туда или контейнер не запущен. Этот же приём годится для healthcheck-обвязки: ни одной лишней зависимости.
Чек-лист живого брокера#
- docker ps показывает контейнер со статусом Up и двумя опубликованными портами.
- http://localhost:15672 открывается и пускает с guest/guest.
- Во вкладке Overview видны версии брокера и Erlang, счётчики сообщений в секунду.
- Вкладка Connections пуста — это нормально: клиентов пока нет.
- docker logs rabbitmq завершается строкой Server startup complete.
- amqp.Dial из первого урока перестаёт падать с connection refused.
Management UI: обзор вкладок#
Management UI — набор вкладок, которые стоит обойти сразу. Overview — самочувствие брокера: сообщения в секунду, память, диск; здесь же корень HTTP API, из которого те же цифры читают скрипты. Connections — открытые TCP-соединения клиентов; каждое — ваш amqp.Dial, и их внезапное количество говорит об утечке соединений в коде. Channels — каналы поверх соединений; счётчик растёт, когда код открывает канал на каждый вызов — классическая ошибка, к которой вернёмся в четвёртом уроке. Exchanges — обменники, включая встроенные с пустым именем и семейство amq.*. Queues — главный экран: глубина очереди, число потребителей, скорость входа и выхода сообщений. Именно на Queues вы будете смотреть, отлаживая, почему письма не уходят: сообщения копятся, а Consumers показывает ноль — значит, воркер не подписался или упал. Admin — пользователи, права и vhost. Панель читается как состояние системы, и приучаться к ней стоит раньше, чем писать собственные дашборды.
Пользователи и vhost: guest только для localhost#
Из коробки в брокере один пользователь — guest с паролем guest, и он жёстко ограничен соединениями с localhost. Контейнер считает localhost'ом себя, а не вашу машину, но из-за проброшенного порта браузер ходит через localhost и авторизуется; из сети та же пара игнорируется брокером нарочно. Для любого реального окружения заводят отдельных пользователей: docker exec rabbitmq rabbitmqctl add_user app пароль, затем rabbitmqctl set_permissions -p / app "." "." ".*" — права читать, писать и конфигурировать на vhost. Vhost — виртуальный хост внутри брокера: изолированное пространство имён с собственными очередями и правами, поэтому стейджинг и рабочий контур на одном сервере живут в разных vhost и не видят очередей друг друга. URL подключения из первого урока заканчивается на слэш — это путь к дефолтному vhost. В Go-коде логин передаётся прямо в amqp://user:pass@host:port/vhost, без отдельных аргументов — и потому попадает в логи вместе со всей строкой, о чём ещё поговорим.
Кейс: контейнер подняли на тестовой VPS с -p 5672:5672 и -p 15672:15672, решив попробовать пару дней. Сканеры обшаривают оба порта непрерывно: guest из сети всё равно не сработает, но панель 15672 остаётся открытой целиком, а попытки входа в логах растут десятками в минуту. Правило: порты публикуют либо на loopback (-p 127.0.0.1:15672:15672), либо закрывают файрволом и ходят по SSH-туннелю; TLS и права пользователей для сети — тема урока про безопасность, а пароль дефолтного пользователя меняют первым делом, если панель всё же смотрит наружу.
Гонка старта: compose up, а брокера ещё нет#
Классическая ловушка окружения: docker compose up поднимает и брокер, и ваш сервис одновременно, сервис стартует быстрее, amqp.Dial падает, контейнер перезапускается, падает снова — и после пары попыток compose сдаётся. Брокеру нужно время: он поднимает Erlang VM, восстанавливает очереди с диска и только потом открывает порт. Решений три, по нарастающей вовлечённости. Healthcheck в compose с условием service_healthy задерживает зависимые сервисы, пока /api/overview не начнёт отвечать. Ретраи с паузой в коде — если compose-файл вы не контролируете. И фейл-фаст с честной ошибкой — когда повторную попытку организует оркестратор вроде Kubernetes, а не ваш main. В споре «кто должен ждать брокера» я на стороне compose и healthcheck: код без ретраев проще, а задержка старта — обязанность инфраструктуры. Мнение не бесспорное: в системах без оркестратора ретраи в коде оказываются единственной защитой от утренних алертов.
Обновление брокера: volume и мажорные версии#
Volume решает половину проблем обновления, но не всё. Именованный volume rabbitmq-data хранит внутреннюю базу с определениями очередей, пользователей и прав, поэтому docker rm вместе с повторным docker run на новом образе переживает данные. Мажорная версия — отдельная история: брокер поднимает данные соседней предыдущей мажорной ветки, например 3.13 на 4.x, но обратного пути нет — с 4.x на 3.x без экспорта не откатиться. Практика делится надвое. В разработке обновляйтесь смело: данные не дороже пересоздания контейнера. В продакшене сначала снимите экспорт определений через rabbitmqctl export_definitions в JSON, затем обновляйте и не прыгайте через несколько мажоров подряд. И последнее: образы с тегом latest в compose-файлах — источник ночных сюрпризов. Сегодня latest — это одна ветка, завтра поведение вкладки Queues меняется, а git blame виноватых не находит, потому что виноват инфраструктурный файл, который никто не открывал месяцами.
waitBroker: проверка с ретраями
GOfunc waitBroker(url string, tries int) error {
client := &http.Client{Timeout: 2 * time.Second}
for i := 0; i < tries; i++ {
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return err
}
req.SetBasicAuth("guest", "guest")
resp, err := client.Do(req)
if err == nil {
resp.Body.Close()
if resp.StatusCode == http.StatusOK {
return nil
}
}
time.Sleep(2 * time.Second)
}
return errors.New("management api не отвечает")
}Та же проверка, что и в первом коде, но в цикле: функция ходит в /api/overview не более tries раз, между попытками спит две секунды и возвращает ошибку, только если брокер так и не ожил. Обратите внимание на resp.Body.Close() — тело закрывают немедленно, иначе в цикле утекут соединения быстрее, чем поднимется брокер. Такой хелпер переезжает из main в тесты и в обвязку старта без изменений.
Всё сетевое в этом курсе выполняется локально: брокер — контейнер Docker из начала урока, Go-код — на вашей машине. Песочница сайта запускает только подмножество стандартной библиотеки (fmt, strings, strconv, math, sort, errors, time) без net/http и сокетов, поэтому проверить панель в браузере урока нельзя. Зато интерактивные задания ниже тренируют именно то, что пригодится в терминале.
Брокер жив, панель знакома, пользователи разобраны — среда готова к первому настоящему клиенту. В следующем уроке подключим amqp091-go через go get, напишем amqp.Dial с таймаутом и разберём URL подключения по частям. Сравнение с другим хранилищем напрашивается само: как и в курсе по go-redis, установка занимает минуты, а вся глубина — в том, что вы делаете дальше. Цифры, которые вы подсмотрели в management UI, со временем переедут в Prometheus — там про них отдельный курс. А сейчас прогоните чек-лист ещё раз, но уже с volume: пересоздание контейнера с данными на месте — обязательный рефлекс перед девятым уроком про durable-очереди. И заодно решите, где будет жить строка подключения — в переменных окружения или в compose-файле: третий урок начнёт именно с неё.
Проверка: порты брокера
Какой порт слушает management UI в контейнере rabbitmq:4-management?
Проверка: гость в сети
Сервис подключается к брокеру на чужой машине с парой guest/guest. Что произойдёт?
Что выведет программа?
Прочитайте код и выберите, что он выведет:
resp, err := http.Get("http://localhost:15672/api/queues")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
fmt.Println(resp.StatusCode)Соберите запрос к management API
Допишите создание запроса, авторизацию, выполнение и закрытие ответа.
Соберите проверку брокера по строкам
Расставьте шаги проверки готовности: клиент, запрос, авторизация, выполнение, закрытие тела, вывод статуса.
Строки
Ваша программа
Нажимайте на строки слева, чтобы собрать программу
Карточки: установка RabbitMQ
Песочница урока
Редактируйте код и запускайте его прямо здесь — интерпретатор работает в браузере, ничего устанавливать не нужно. За каждый запуск — +2 XP.
Запустите код, чтобы увидеть вывод.
Коротко: что запомнить
- docker run с образом rabbitmq:4-management поднимает брокер и панель одной командой.
- 5672 — AMQP для клиентов, 15672 — management UI и его HTTP API, 5671 — TLS.
- guest/guest работает только с localhost; для сети заводят пользователей и vhost через rabbitmqctl.
- Management UI — первая линия диагностики: Queues, Connections и Channels читаются как состояние системы.
- Данные брокера держат в volume, иначе recreate контейнера стирает пользователей и очереди.
- Гонку старта закрывают healthcheck и service_healthy, а не ретраями в main.
Домашнее задание
Поднимите брокера с именованным volume: docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 -v rabbitmq-data:/var/lib/rabbitmq rabbitmq:4-management. Проверьте панель на localhost:15672, создайте пользователя app через rabbitmqctl, затем пересоздайте контейнер и убедитесь, что пользователь пережил recreate.
Личные заметкиПусто
Вопросы и ответы по уроку
Какая версия RabbitMQ ставится для курса?
Образ rabbitmq:4-management — актуальная мажорная версия 4.x с панелью. Для учебных задач разница с веткой 3.13 несущественна, но тег фиксируйте: плавающий latest однажды подменит поведение между запусками, и искать причину вы будете в коде зря.
Можно ли поставить RabbitMQ без Docker?
Можно: есть пакеты для Debian, Ubuntu, Windows и Homebrew для macOS. В разработке Docker удобнее версионированием и чистотой системы, а в продакшене контейнер или готовый образ — обычное дело, поэтому навык установки через docker переносится один в один.
Почему management UI показывает 401, хотя пароль верный?
Сначала проверьте, что пара вообще передаётся: API отвечает 401 на любой запрос без заголовка Authorization. Второй кандидат — перепутанные порты: 15672 для панели и её API, 5672 для AMQP-клиентов; путаница стоит десятков минут.
Термины урока
Ключевые понятия из этого урока — короткие определения в глоссарии. Наведите на термин, чтобы вспомнить, откройте карточку для подробностей и ссылки на практику.
Изучайте дальше
Следующая ступень учебного пути
Excel в Go: чтение и генерация xlsx на excelize
Курс excelize на Go: создание xlsx, чтение, стили, формулы, диаграммы и StreamWriter для больших файлов. 25 уроков с примерами кода и проектом.
- Создавать и читать xlsx-файлы средствами excelize
- Работать с листами, ячейками, строками и столбцами
- Оформлять таблицы: стили, шрифты, границы, форматы чисел и дат
- Вставлять формулы, диаграммы и изображения