Ответ
RabbitMQ — это популярный и надежный брокер сообщений (message broker) с открытым исходным кодом. Он выступает в роли посредника между различными частями приложения (сервисами), позволяя им обмениваться сообщениями асинхронно.
Проще говоря, это как почтовое отделение для ваших приложений: один сервис отправляет «письмо» (сообщение), RabbitMQ принимает его и доставляет в «почтовый ящик» (очередь) другого сервиса, который заберет его, когда будет готов.
Основные компоненты:
- Producer: Поставщик, который отправляет сообщения.
- Exchange: Обменник, который получает сообщения от поставщиков и направляет их в нужные очереди на основе правил маршрутизации.
- Queue: Очередь, которая хранит сообщения до тех пор, пока их не заберет потребитель.
- Consumer: Потребитель, который подписывается на очередь и обрабатывает сообщения.
Зачем он нужен в бэкенде? Основные сценарии использования:
- Асинхронные задачи: Выполнение долгих операций (отправка email, обработка видео, генерация отчетов) в фоновом режиме, не блокируя основной поток приложения и не заставляя пользователя ждать.
- Коммуникация между микросервисами: Обеспечение слабой связанности (loose coupling) сервисов. Сервисы общаются не напрямую, а через брокера, что повышает отказоустойчивость и гибкость системы.
- Балансировка нагрузки: Если на одну очередь подписано несколько потребителей (workers), RabbitMQ будет распределять сообщения между ними, позволяя горизонтально масштабировать обработку задач.
- Гарантированная доставка: RabbitMQ может сохранять сообщения на диск (persistent messages), чтобы они не потерялись в случае сбоя или перезапуска брокера.
Пример на Go (отправка сообщения):
// Устанавливаем соединение
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
// ... обработка ошибок
defer conn.Close()
ch, err := conn.Channel()
// ... обработка ошибок
defer ch.Close()
// Объявляем очередь, куда будем отправлять сообщения
q, err := ch.QueueDeclare(
"hello", // имя очереди
false, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
body := "Hello, RabbitMQ!"
// Публикуем сообщение в очередь
err = ch.Publish(
"", // exchange (пусто - используется default exchange)
q.Name, // routing key (имя очереди для default exchange)
false, // mandatory
false, // immediate
amqp.Publishing{
ContentType: "text/plain",
Body: []byte(body),
})