Очереди сообщений и асинхронность
Как разорвать жёсткую связь между сервисами и пережить всплески нагрузки.
Очередь сообщений — буфер между producer и consumer, который позволяет обрабатывать задачи асинхронно, развязывая отправителя и получателя по времени и нагрузке.
Зачем нужна очередь
Если загрузка фото запускает синхронно нарезку превью, распознавание и индексацию, пользователь ждёт всё это. Вынесем тяжёлую работу в очередь: API быстро отвечает «принято», а consumer'ы делают остальное в фоне. Так система становится отзывчивее и устойчивее к пикам.
Producer -> [ Очередь ] -> Consumer 1
-> Consumer 2 (масштабируем независимо)Три главные выгоды
| Выгода | Суть |
| Развязка | Producer не знает про consumer, можно менять независимо |
| Сглаживание пиков | Всплеск копится в очереди, обрабатывается ровно |
| Масштаб consumer'ов | Добавляем обработчиков под рост очереди |
Гарантии доставки
Большинство брокеров дают at-least-once: сообщение точно дойдёт, но может прийти повторно. Отсюда требование — consumer должен быть идемпотентным, чтобы повторная обработка не навредила (например, не списать дважды). Exactly-once дорог и редко нужен.
Как работает под капотом
Очередь превращает синхронную цепочку «запрос -> вся работа -> ответ» в асинхронную «запрос -> ответ + задача в фоне». Это вводит новые заботы: что если consumer упал (сообщение вернётся в очередь), что с «ядовитыми» сообщениями (dead-letter queue), как не потерять порядок (партиции/ключи). На собеседовании достаточно назвать эти заботы — это показывает зрелость.
Частые ошибки
- Делать всё синхронно и блокировать пользователя на тяжёлой работе.
- Забыть про идемпотентность при at-least-once доставке.
- Не предусмотреть dead-letter queue для битых сообщений.
Итог
- Очередь развязывает сервисы, сглаживает пики и масштабирует фон.
- at-least-once -> consumer обязан быть идемпотентным.
- Помните про падения consumer'ов, dead-letter и порядок сообщений.