Какие типы очередей существуют в RabbitMQ и в чем их ключевые различия?

Ответ

В RabbitMQ существует несколько основных типов очередей, каждый из которых предназначен для решения определённых задач.

  1. Classic Queues (Классические очереди)

    • Это стандартные очереди, работающие по принципу FIFO (First-In, First-Out).
    • Являются универсальным решением для большинства стандартных сценариев.
    • Могут быть durable (сохраняются на диске и переживают перезапуск брокера) или transient (хранятся в памяти и удаляются при перезапуске).
  2. Quorum Queues (Кворумные очереди)

    • Представлены в RabbitMQ 3.8. Это современная реализация реплицируемых очередей, предназначенная для обеспечения высокой доступности и целостности данных.
    • Используют протокол консенсуса Raft для репликации.
    • Рекомендуются к использованию вместо устаревших mirrored queues для построения отказоустойчивых систем.
  3. Stream Queues (Потоковые очереди)

    • Добавлены в RabbitMQ 3.9. Оптимизированы для сценариев с очень большим потоком сообщений (логи, метрики, события).
    • Работают как лог с возможностью чтения с определённого смещения (offset), подобно Apache Kafka.
    • Поддерживают очень большие объёмы данных и множество потребителей, читающих один и тот же поток сообщений.

Специализированные очереди и механизмы:

  • Priority Queues (Приоритетные очереди): Позволяют обрабатывать сообщения с более высоким приоритетом в первую очередь. Приоритет задаётся при публикации сообщения.
  • Lazy Queues (Ленивые очереди): По умолчанию стараются как можно дольше держать сообщения на диске, а не в памяти. Это полезно для очень длинных очередей, чтобы снизить потребление RAM.
  • Dead-Letter Exchange (DLX): Это не тип очереди, а механизм для обработки "мёртвых" сообщений. Если сообщение не может быть обработано (например, отклонено потребителем без перепостановки в очередь), оно отправляется в специальный обменник (DLX), к которому может быть привязана очередь для анализа и повторной обработки таких сообщений.
// Пример объявления классической durable очереди в Go
ch, err := conn.Channel()
// ... обработка ошибки

q, err := ch.QueueDeclare(
  "my_classic_queue", // name - имя очереди
  true,               // durable - true, если очередь должна пережить перезапуск брокера
  false,              // delete when unused - удалить, когда нет потребителей
  false,              // exclusive - эксклюзивный доступ для текущего соединения
  false,              // no-wait - не ждать ответа от сервера
  nil,                // arguments - дополнительные аргументы (для priority, lazy, dlx и т.д.)
)