1. RabbitMQ: время и контекст
Если бы мы добавили RabbitMQ в самом начале курса, это выглядело бы эффектно, но методически было бы похоже на попытку учиться водить машину сразу на гоночном болиде: вроде бы круто, но вы ещё не уверены, где педаль тормоза, и очень быстро окажетесь в кустах. RabbitMQ — это не «сложнее Docker», он просто добавляет ещё один тип зависимости, который нужно уметь поднимать, конфигурировать и диагностировать в Compose-окружении.
Именно сейчас мы уже имеем устойчивую базу: стек app + postgres + redis работает, профили у нас не превратились в конфигурационный лабиринт, а логи мы умеем читать не как художественную литературу, а как технические доказательства. RabbitMQ логично добавлять после этого фундамента, потому что иначе любая ошибка будет выглядеть одинаково: «всё сломалось», и вы не сможете отличить, что именно сломалось — база, кэш, приложение или ваша вера в localhost.
Есть ещё одна важная причина «почему сейчас». До RabbitMQ у нас были зависимости, которые обычно воспринимаются как «хранилище» (PostgreSQL) и «ускоритель чтений» (Redis). RabbitMQ добавляет третий класс: посредник для сообщений. Это полезно даже на минимальном уровне, потому что типичный backend-проект в реальной жизни часто имеет хотя бы один такой компонент: либо RabbitMQ, либо Kafka, либо какой-нибудь managed broker в облаке. Мы не превращаем курс в messaging-track, но показываем: вот так выглядит зрелое локальное окружение, где кроме БД и кэша есть ещё и broker.
Наконец, это хороший момент для дисциплины мышления: добавление новой зависимости не должно вести к “переписыванию всего приложения”. Мы не делаем второй сервис, не делаем микросервисы, не вводим отдельный “docker-режим” кода. Мы делаем ровно то, что уже делали раньше: добавляем сервис в Compose, включаем профиль и проверяем минимальный сценарий.
2. RabbitMQ как инфраструктура
Есть опасный момент, который хочется поймать сразу, пока он не убежал: RabbitMQ действительно может быть частью большой архитектуры (с топологиями, обменниками, ключами маршрутизации, ретраями, DLQ, дедупликацией и философскими спорами «у нас event-driven или просто очередь»). Но сегодня мы туда не идём, потому что наш курс про Docker/Compose как ежедневный инструмент Java-разработчика, а не про то, как стать брокерным шаманом.
В нашем контексте RabbitMQ — это такой «почтовый отдел» внутри локального стенда. Приложение кладёт туда «письмо» (сообщение), а потом кто-то это письмо забирает. Это удобно как учебная модель, потому что позволяет сделать минимум, который проверяет wiring окружения: broker поднялся, приложение подключилось, сообщение ушло, сообщение пришло. Всё. Без фанатизма и без “а давайте спроектируем систему как в FAANG” (что обычно означает «давайте усложним себе жизнь, чтобы потом героически её упрощать»).
Важно также удержать границу проекта. Наш Container-Ready Catalog Service остаётся одним Spring Boot приложением. RabbitMQ не заставляет нас делать второй сервис-потребитель. Мы можем получить сообщение внутри того же приложения (через @RabbitListener) и просто залогировать факт получения. В реальном продукте, конечно, чаще будут разные сервисы. Но здесь цель другая: показать Compose-стек и конфигурационную дисциплину, а не построить distributed system.
Если сказать совсем честно: сегодня RabbitMQ нужен нам как «ещё один контейнер, к которому приложение должно уметь подключаться по service name». Мы тренируем не брокер, а умение не теряться, когда в стеке становится на один сервис больше.
3. Что должно получиться к концу дня
Здесь важно не перепутать цель. Сегодня достаточный результат — не «изучили RabbitMQ вообще», а аккуратно встроили ещё одну зависимость в тот же Compose-стенд и не превратили проект в новый архитектурный трек.
К концу уровня должно быть понятно три вещи:
— где живёт rabbitmq в compose.yaml и как приложение находит его по service name;
— как messaging включается как ещё один runtime-режим того же Spring Boot приложения;
— по какому минимальному признаку видно, что связка реально работает: сообщение ушло и дошло, а это видно в логах.
Если эти три пункта собираются в одну причинно-следственную цепочку, уровень уже сделал свою работу.
4. Из чего состоит этот шаг
Порядок здесь важен. Сначала нужен сам broker как обычный Compose service: понятное имя rabbitmq, нормальные порты и быстрый способ проверить, что контейнер вообще жив. Потом — runtime-конфиг приложения: тот же image, но с messaging профилем и параметрами подключения, а не отдельный jar и не новый Dockerfile.
И только после этого есть смысл смотреть на один короткий путь сообщения: HTTP-действие вызвало отправку, RabbitMQ принял сообщение, listener его получил, а в логах остались обе точки. Этого достаточно, чтобы стенд стал реалистичнее и при этом не распался на второй сервис, второй build-path и новую религию «а давайте сразу спроектируем event-driven вселенную».
5. Типичные ошибки при работе с RabbitMQ
Ошибка №1: ожидание “сегодня мы изучим RabbitMQ целиком”.
RabbitMQ — большая тема, и её можно изучать месяцами, особенно если начать читать про topology, гарантии доставки и “как правильно проектировать event-driven архитектуру”. В рамках этого курса RabbitMQ — инфраструктурный компонент стенда. Если держать ожидание “минимальный wiring и минимальный обмен”, материал становится гораздо понятнее и не вызывает ощущения “мне недодали”.
Ошибка №2: попытка превратить проект в несколько сервисов.
Частая реакция на слово “broker”: “о, значит надо сделать отдельный consumer-сервис!”. В реальном мире это часто так, но в нашем учебном проекте это мгновенно увеличит поверхность сложности: второй сервис, второй Dockerfile, второй lifecycle, и вы начнёте учить микросервисы вместо Compose. Мы остаёмся в одном приложении и используем broker как dependency.
Ошибка №3: желание “сразу сделать красиво” — несколько очередей, exchange’ов и сложные сообщения.
Это выглядит как забота о будущем, но по факту ломает последовательность. Сегодня нам нужно увидеть один прозрачный путь сообщения. Как только появляется несколько очередей, routing и сложный payload, вы начинаете отлаживать именование и конфигурацию, а не Compose-связность.
Ошибка №4: уход в архитектурные споры раньше, чем собран сам стенд.
На этом месте легко уйти в разговоры “а почему не Kafka”, “а нужен ли вообще async”, “а где здесь event-driven architecture”. Всё это интересные вопросы, но они не помогают вам сегодня встроить broker в Compose-стек. Сначала нужен работающий wiring, а уже потом — любые большие споры о мире.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ