С нуля: что такое очередь сообщений на самом деле
Очередь сообщений — буфер, позволяющий одному сервису передать работу другому без ожидания. Это карта «с нуля» и восемь слов, которые юнит о гарантиях доставки считает уже знакомыми.
Твоё веб-приложение неожиданно завирусилось. При каждой регистрации ты отправляешь приветственное письмо — а почтовый провайдер медленный. Теперь каждый запрос на регистрацию висит три секунды, пока письмо не уйдёт. Трафик удвоился — сервер встал. Решение не в более быстром провайдере. Решение — перестать ждать. Очередь сообщений позволяет обработчику регистрации сказать «кто-нибудь отправьте это письмо» и сразу продолжить работу, пока отдельный процесс подберёт задачу и выполнит её в своём темпе. Этот урок — карта, после которой такое решение станет понятным.
Единственная проблема, которую решают очереди сообщений
Два сервиса, общающихся напрямую, связаны в момент вызова: если Сервис Б медленный — Сервис А ждёт; если Сервис Б упал — Сервис А падает тоже. Очереди сообщений разрывают эту связь. Сервис А кладёт сообщение в общий буфер и сразу продолжает работу. Сервис Б читает из буфера когда готов. Оба сервиса никогда не обязаны быть живыми одновременно, а всплеск нагрузки просто увеличивает буфер, а не роняет отправителя.
Всё в треке queues — гарантии доставки, партиционирование, порядок, паттерн outbox — это детали поверх одной идеи: отдели отправителя от получателя, дав сообщению место, где оно может подождать.
Восемь слов, которые остальной трек считает знакомыми
Senior-юниты дальше используют эти термины, не останавливаясь на определениях. Вот они, по одному предложению — что это и зачем оно.
| Слово | Что это | Зачем оно |
|---|---|---|
| Сообщение (message) | Единица данных, которую один сервис отправляет, чтобы другой её обработал. | Чтобы работу можно было описать один раз и обработать где угодно и когда угодно. |
| Производитель (producer) | Сервис, который создаёт и публикует сообщение. | Чтобы отправитель отвечал только за публикацию, а не за то, что будет дальше. |
| Потребитель (consumer) | Сервис, который читает и обрабатывает сообщение. | Чтобы обработку можно было масштабировать, заменять или приостанавливать независимо от производителя. |
| Очередь vs топик | Очередь доставляет каждое сообщение одному потребителю; топик — всем подписчикам. | Чтобы выбирать: работу забирает один воркер или оповещаются все слушатели. |
| Брокер (broker) | Сервер (например, Kafka, RabbitMQ), который хранит и маршрутизирует сообщения. | Чтобы производителю и потребителю не нужно было знать адрес и расписание друг друга. |
| Асинхронное разделение | Производитель продолжает работу сразу после публикации; обработка происходит позже. | Чтобы медленный или упавший потребитель не делал медленным или упавшим производителя. |
| Подтверждение (ack) | Сигнал, который потребитель отправляет брокеру после успешной обработки сообщения. | Чтобы брокер знал, что сообщение обработано, и мог удалить его, а не переотправить. |
| Бэклог / лаг (backlog) | Количество сообщений в очереди, ещё не обработанных потребителем. | Чтобы видеть, успевают ли потребители, и масштабировать их, когда отстают. |
Как они складываются вместе
Прочитанные по порядку, слова рассказывают одну историю: производитель публикует сообщение в брокер; брокер хранит его в очереди (или рассылает всем подписчикам через топик). Потребитель читает сообщение в своём темпе и отправляет ack брокеру, как только работа выполнена. Пока ack не пришёл — брокер держит сообщение готовым к переотправке, так что ничего не теряется незаметно. Разница между опубликованными и подтверждёнными сообщениями в каждый момент — это бэклог, живой сигнал здоровья системы. Вся конструкция — асинхронное разделение: производитель свободен в момент публикации, а потребитель может работать на любой машине, в любом темпе, и производителю это неважно.
Когда в следующих юнитах ты встретишь гарантии, порядок или сбои — каждый из них будет описываться через эти восемь ролей; если термин покажется незнакомым, эта таблица — твоя точка возврата.
▸Почему это работает
Почему бы просто не вызвать другой сервис напрямую через HTTP? Потому что такой вызов синхронный: оба сервиса должны быть живы в одно и то же мгновение, и вызывающий висит, пока вызываемый не ответит. В длинной цепочке сервисов один медленный нижний делает медленными всех выше. Очередь поглощает всплеск: производитель публикует и возвращается за микросекунды; потребитель разгребает бэклог в своём темпе. Очередь работает как амортизатор — резкий всплеск трафика увеличивает бэклог, а не частоту ошибок.
Что потребитель отправляет брокеру после успешной обработки сообщения и почему это важно?
Расставь путь сообщения от создания до завершения:
- 1 Производитель публикует сообщение в брокер
- 2 Брокер хранит сообщение в очереди
- 3 Потребитель читает сообщение и обрабатывает его
- 4 Потребитель отправляет ack; брокер удаляет сообщение
- 01В одном дыхании: какую проблему решают очереди сообщений и в чём ядро механизма?
- 02Проследи путь одного сообщения от публикации до удаления, называя каждого участника и его роль.
Очереди сообщений решают одну проблему: два сервиса, вызывающие друг друга напрямую, связаны во времени — когда один медленный или упавший, другой страдает. Очереди разрывают эту связь, давая сообщениям место для хранения. Производитель публикует сообщение в брокер и сразу продолжает работу; потребитель читает из брокера когда готов и подтверждает каждое сообщение ack-ом по завершении; брокер держит сообщение до получения ack, чтобы ничего не потерялось незаметно. Бэклог — неподтверждённые сообщения — это живой сигнал здоровья потребителей. Очередь доставляет одному; топик рассылает всем подписчикам. Этот словарь — сообщение, производитель, потребитель, брокер, ack, бэклог, асинхронное разделение — будет использоваться во всех юнитах без дополнительных определений. Теперь, когда встретишь сообщение, у которого «пропал ack», ты сразу поймёшь: брокер по-прежнему держит его и готов переотправить — именно так система защищает работу от молчаливой потери.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.