Ответ
RabbitMQ применялся в проектах для асинхронной коммуникации и повышения отказоустойчивости. Основные сценарии использования:
- Фоновая обработка задач: Отправка email, генерация отчетов PDF или обработка загруженных изображений. Пользовательский запрос не блокируется, а задача ставится в очередь.
- Интеграция микросервисов: Слабая связность между сервисами. Например, сервис заказов публикует событие
OrderPlaced, а сервис доставки и сервис уведомлений подписываются на него независимо. - Балансировка нагрузки (Work Queues): Распределение задач между несколькими экземплярами воркеров для горизонтального масштабирования.
- Гарантированная доставка: Использование подтверждений (acknowledgments) и устойчивых (durable) очередей гарантирует, что сообщение не потеряется при перезапуске брокера или воркера.
- Pub/Sub (Publish/Subscribe): Рассылка одного сообщения множеству потребителей. Например, уведомление всех онлайн-пользователей о системном событии.
Пример публикации сообщения на C# (RabbitMQ.Client):
var factory = new ConnectionFactory() { HostName = "rabbitmq-host" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
// Объявляем durable очередь
channel.QueueDeclare(queue: "order.queue",
durable: true, // Сохранить очередь при перезапуске
exclusive: false,
autoDelete: false,
arguments: null);
var message = JsonSerializer.Serialize(new { OrderId = 123, Action = "Process" });
var body = Encoding.UTF8.GetBytes(message);
// Публикуем с флагом persistent
var properties = channel.CreateBasicProperties();
properties.Persistent = true; // Сохранить сообщение на диске
channel.BasicPublish(exchange: "",
routingKey: "order.queue",
basicProperties: properties,
body: body);
Console.WriteLine($"Sent: {message}");
Почему RabbitMQ: Надежность, поддержка различных протоколов (AMQP 0-9-1), гибкая маршрутизация через exchanges, хорошая экосистема и управление через веб-интерфейс.
Ответ 18+ 🔞
Да, блядь, RabbitMQ! Вот это тема, я тебе скажу. Мы его впихивали в проекты, когда нужно было, чтобы сервисы между собой общались, но не синхронно, в лоб, а как бы... изящно, понимаешь? Чтобы если один сервис лег, остальные не охуели сразу, а продолжали работать.
Основные сценарии, где он выручал, вот:
-
Фоновые задачи, эти ваши. Ну, например, пользователь нажал «отправить отчёт». А ему не нужно ждать, пока этот пиздец на 500 страниц сгенерируется. Мы просто кидаем задачку в очередь: «эй, сгенерируй отчёт для Василия». А система спокойно, не торопясь, её оттуда выковыривает и делает. Пользователь уже чай пьёт, а отчёт ему на почту прилетает. Красота.
-
Микросервисы, чтобы не перепихивались локтями. Раньше всё в одном монолите сидело — один упал, все пошли нахуй. А тут сервис заказов сделал своё дело и крикнул в очередь: «Чуваки, заказ №123 создан!». И два других сервиса — доставки и уведомлений — независимо друг от друга этот крик услышали и начали своё грязное дело. Слабая связность, ебать её в сраку, это же сила.
-
Балансировка нагрузки, чтоб её. Представь, у тебя куча тяжёлых задач и один воркер. Он сдохнет, бедолага. А мы накидываем ему в помощь ещё пять таких же. RabbitMQ сам раскидает задачи между ними, как умная мамаша конфеты детям. Горизонтальное масштабирование, ёпта!
-
Чтобы ничего не терялось, вот что главное. Включил подтверждения (acknowledgments) и объявил очередь устойчивой (durable) — и можно хоть сервер вырубить из розетки. Поднимешь — очередь на месте, сообщения целы. Не то что эти ваши in-memory очереди, которые чихнул — и всё, пиздец, прощай логика.
-
Широковещательная рассылка (Pub/Sub). Одно событие — а получателей дохуя. Например, «система будет перезагружена в 3 ночи». И это сообщение получат и сервис оповещения пользователей в вебе, и мобильное приложение, и ещё какая-нибудь админская панель. Все в курсе, все готовятся.
Вот, смотри, как на C# (через RabbitMQ.Client) отправить сообщение, чтобы оно не потерялось:
var factory = new ConnectionFactory() { HostName = "rabbitmq-host" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
// Объявляем очередь DURABLE, чтобы пережила перезагрузку
channel.QueueDeclare(queue: "order.queue",
durable: true, // Вот эта хуйня главная!
exclusive: false,
autoDelete: false,
arguments: null);
var message = JsonSerializer.Serialize(new { OrderId = 123, Action = "Process" });
var body = Encoding.UTF8.GetBytes(message);
// А тут делаем само сообщение PERSISTENT, чтобы на диск легло
var properties = channel.CreateBasicProperties();
properties.Persistent = true; // И вот эта тоже!
channel.BasicPublish(exchange: "",
routingKey: "order.queue",
basicProperties: properties,
body: body);
Console.WriteLine($"Sent: {message}");
А почему вообще RabbitMQ, а не что-то другое? Ну, во-первых, надёжный как швейцарские часы, если правильно настроить. Во-вторых, у него там гибкая маршрутизация через эти ваши exchange'и — можно сообщения по разным правилам раскидывать, прям как почтальон Печкин. В-третьих, есть удобный веб-интерфейс, где видно, что в какой очереди творится, сколько сообщений зависло. И протокол AMQP — это стандарт де-факто, куча клиентов под все языки. В общем, инструмент серьёзный, для взрослых дядек.