Человек запросил большой отчёт, а приложение отвечает: «Задание принято». Это ещё не готовый файл. Между запросом и результатом есть работа, которую может выполнить отдельный процесс. В Гуси-Лебеди мы предлагаем обсуждать очереди сообщений с этого различия: что система приняла, что уже обработала и как пользователь узнает о результате.
Очередь сообщений помогает передать данные или задание от программы-отправителя программе-получателю. Брокер организует обмен между участниками. Отправитель и обработчик могут работать в разное время, поэтому запрос пользователя не обязательно должен ждать завершения всей фоновой операции. Но очередь сама по себе не гарантирует выполнение, отсутствие дублей или сохранность данных при любом сбое.
RabbitMQ и Apache Kafka часто обсуждают рядом, хотя их основные модели различаются. Для выбора важно понять, нужно ли передавать задания исполнителям, хранить поток событий для повторного чтения, доставлять сведения нескольким системам или сочетать эти сценарии. Разберём эти вопросы на условном примере подготовки отчёта, без обещаний производительности, которые не проверены на вашем приложении.
Когда обсуждать фоновую обработку

В условном примере приложение должно подготовить отчёт. Пользователь выбирает период, отправляет запрос и получает идентификатор задания. Отдельный исполнитель собирает данные и сохраняет файл. Интерфейс показывает готовность только после подтверждённого результата, а до этого сообщает о подготовке или ошибке. Такой путь позволяет отделить короткий запрос от длительной работы.
Участники обмена имеют разные обязанности. Producer создаёт и публикует сообщение. Брокер организует его передачу и хранение в рамках выбранной модели. Consumer получает сообщение и выполняет обработку. Эти роли могут принадлежать разным сервисам или процессам одного приложения; наличие очереди не требует автоматически делить весь проект на микросервисы.
Сначала выясните, допускает ли задача ожидание. Проверку, от которой зависит немедленное разрешение действия, нельзя просто перенести в фон и показать пользователю окончательный успех. Для подготовки отчёта можно согласовать ожидание и уведомление. Для других операций нужно отдельно определить, какой промежуточный ответ действительно допустим.
Почему очередь не устраняет перегрузку сама
Очередь может накапливать задания во время краткого всплеска и позволять исполнителям разбирать их с доступной скоростью. Но если новые задания постоянно поступают быстрее обработки, ожидание растёт. Нужно проверять производительность исполнителей, ограничения зависимых систем и допустимое время ожидания, а не считать наличие брокера решением любой нагрузки.
Мы советуем до выбора инструмента описать, как человек узнает о готовности, сможет ли вернуться к задаче после закрытия страницы и что увидит при сбое. Рядом укажите, кто сопровождает обработку. Если более простое решение обеспечивает нужное поведение, его стоит сравнить с отдельным брокером: новый компонент тоже требует настройки, наблюдения и восстановления.
Можно ли обойтись таблицей заданий
Отдельный брокер не обязателен для любого фонового действия. На обсуждение архитектуры можно принести и вариант с таблицей заданий в существующей базе: приложение сохраняет задание, исполнитель забирает его и записывает результат. Сравнивать нужно поведение при сбоях и одновременной работе нескольких исполнителей. Кто получит задание, если его уже забрал другой процесс? Как вернуть зависшую работу после остановки? Как не потерять запись о задаче при сохранении основных данных? Эти вопросы остаются и у простого решения. Брокер выбирают под конкретные требования к обмену и сопровождению, а не только потому, что операция выполняется в фоне.
Как сравнивать RabbitMQ и Kafka по задаче

Начните с различия задания и события. «Подготовить отчёт» просит выполнить работу. «Отчёт подготовлен» сообщает о произошедшем факте. Разным получателям могут понадобиться разные сведения: исполнитель готовит файл, интерфейс показывает статус, а аналитическая система учитывает событие. Это описание нашего примера, а не обязательная архитектура любого проекта.
В руководстве RabbitMQ по рабочим очередям задания распределяются между исполнителями. Подтверждение обработки помогает брокеру определить, когда сообщение можно удалить; при потере соединения неподтверждённое сообщение может попасть на повторную обработку. Возможность повторной доставки нужно учитывать в самой операции.
В официальном введении Apache Kafka описана модель потока событий. Записи хранятся в топиках и не удаляются только потому, что их прочитали. Срок хранения задаётся настройками. Топик состоит из разделов, или партиций; порядок чтения связан с конкретной партицией, а не со всеми событиями системы сразу.
| Вопрос проекта | Что нужно согласовать |
|---|---|
| Передаём задание или сохраняем событие? | Кто выполняет работу и кому нужен её результат |
| Нужен один исполнитель или несколько независимых получателей? | Как сведения распределяются между участниками |
| Требуется повторно читать историю? | Как долго данные доступны и кто управляет повторным чтением |
| Порядок влияет на результат? | Какие сообщения образуют одну последовательность |
| Получатель временно недоступен? | Что сохраняется, как долго и как восстанавливается обработка |
Сравнивайте конкретные конфигурации и поведение. У RabbitMQ есть разные способы обмена, а выбор Kafka также не отменяет настройки хранения и обработки. Не сводите решение к лозунгу «RabbitMQ для маленьких проектов, Kafka для больших». Размер проекта сам по себе не описывает требования к доставке, истории и восстановлению.
Если важна производительность, задайте профиль нагрузки, размер сообщений, действия получателей и условия испытания. Без сопоставимого теста нельзя обоснованно заявить, что один инструмент будет быстрее в вашем приложении. А результат доставки проверяйте отдельно от времени выполнения самой бизнес-операции.
Как согласовать повторы, ошибки и статусы

Разделите путь операции на наблюдаемые состояния. Приложение создало задание, передало сообщение, исполнитель начал работу, результат сохранён, пользователь получил доступ к файлу. Эти события не равнозначны. Одна запись «отправлено» не объясняет, на каком этапе остановилась подготовка отчёта.
В RabbitMQ подтверждение публикации со стороны брокера и подтверждение обработки со стороны потребителя решают разные вопросы. Publisher confirm относится к принятой брокером публикации, а consumer acknowledgement сообщает о доставке, за которую отвечает обработчик. Ни одно из них само по себе не подтверждает, что пользователь получил правильный отчёт. Момент подтверждения обработки нужно связать с фактическим выполнением согласованной операции.
Если работа выполнена, а подтверждение потерялось
Представим условный сбой: исполнитель сохранил отчёт, но соединение оборвалось до подтверждения обработки сообщения. При повторной доставке другой исполнитель может получить то же задание. Если обработчик всегда начинает работу заново, получится повторная операция. Это возможный сценарий для проверки, а не сообщение о неисправности вашего приложения.
Согласуйте идентификатор задачи и способ определения уже полученного результата. Повтор одной операции должен иметь заранее выбранное поведение: вернуть существующий файл, безопасно повторить подготовку или перейти к разбору ошибки. Решение зависит от задачи. Для действий с внешним эффектом, например отправки уведомления, отдельно проверяют, не выполнится ли эффект дважды.
Такую защиту часто обсуждают через идемпотентность: повтор не должен создавать дополнительный результат там, где по правилам нужна одна операция. Одного поля с идентификатором недостаточно. Нужно проверить, как обработчик использует его и что происходит при одновременных попытках. Если фиксация результата и побочное действие разделены, возможный сбой между ними тоже требует решения.
Какие ошибки повторять
Временная недоступность зависимого сервиса и некорректные входные данные требуют разного поведения. Повтор после восстановления соединения может помочь первой задаче. Повтор того же неверного сообщения не исправляет данные. Укажите ограничение попыток, паузы, порядок уведомления и место разбора заданий, которые не удалось обработать. Значения выбирают под требования проекта, а не по универсальному числу из статьи.
Если используется отдельная очередь для проблемных сообщений, согласуйте, кто её просматривает, как исправляет причину и как возвращает задания в обработку. Наличие такого места ещё не означает, что ошибки замечены и разобраны. Для пользователя важно видеть честный статус, а для ответственного сотрудника получать сведения, по которым можно найти исходную операцию.
Порядок также задайте явно. Какие обновления относятся к одному объекту? Можно ли применить старое состояние после нового? Что делать с опоздавшим событием? Не переносите порядок получения сообщений на порядок завершения параллельной работы. Обработчики могут выполнять разные задания с разной длительностью.
Как принимать решение и организовывать контроль

Приёмка должна проверять полный путь задачи, а не только успешное подключение к брокеру. Для условного отчёта подготовьте известные входные данные, отправьте задание, дождитесь результата и сопоставьте файл с параметрами запроса. Затем пройдите предусмотренные сбои в согласованной тестовой среде.
| Проверочная ситуация | Что наблюдать |
|---|---|
| Один запрос без сбоев | Идентификатор, изменение статуса и правильный результат |
| Повтор того же задания | Согласованное поведение без лишнего побочного действия |
| Остановка исполнителя | Судьбу начатой работы и восстановление обработки |
| Недоступная зависимая система | Попытки, паузы, видимую ошибку и уведомление |
| Некорректное сообщение | Отказ от бесконечного повтора и возможность разбора |
| Всплеск запросов | Изменение ожидания и работу исполнителей после всплеска |
Эти проверки не проводились на вашем приложении: таблица предлагает план приёмки. Настройки хранения, подтверждений и восстановления нужно проверять для выбранного инструмента и конфигурации. Не считайте отметку persistent или durable обещанием отсутствия потерь при любом отказе.
Для сопровождения полезны разные показатели. Число ожидающих сообщений показывает накопление работы. Возраст старого задания помогает заметить долгое ожидание. Количество сообщений в обработке и ошибок помогает выяснить, где нужна диагностика. Для Kafka отдельно рассматривают отставание потребителя от доступных записей. Значения имеют смысл вместе с интенсивностью поступления, временем обработки и состоянием зависимых систем.
У каждого уведомления должен быть получатель и понятное действие. Согласуйте, кто проверяет задержку, где ищет задачу по идентификатору и как восстанавливает обработку. Не назначайте универсальный допустимый размер очереди: одинаковое число сообщений означает разную работу для короткого уведомления и большого отчёта.
При разработке серверной логики и фоновых процессов эти правила стоит включать в задание вместе с пользовательскими статусами. А проверку под согласованной нагрузкой можно связать с отдельным планом нагрузочного тестирования. Тогда выбор брокера опирается на поведение операции и результаты проверок, а не на популярность названия.
