Message queues & event-driven basics
Тема дорожной карты · DevOps Engineer
Message queues и event-driven архитектура — два связанных, но не идентичных подхода. Очередь — это структура данных для асинхронной передачи команды от одного сервиса другому, обычно с гарантией "доставлено хотя бы раз" (at-least-once). Event-driven — это архитектурный стиль, где сервисы публикуют факты о произошедшем (order.created, payment.confirmed), а другие сервисы реагируют на них. На практике эти подходы часто сосуществуют: очередь — транспорт, event-driven — модель данных.
Как это работает
Базовые гарантии очередей: at-most-once (доставка не более одного раза, возможна потеря), at-least-once (минимум один раз, возможны дубли), exactly-once (ровно один раз, дорого и редко реально достижимо). Большинство production-систем выбирают at-least-once + идемпотентный consumer. Consumer подтверждает (ack) обработку сообщения; до ack оно остаётся в очереди и в случае падения будет перевыдано. Очередь может быть FIFO (порядок сохраняется) или unordered (быстрее, без гарантии порядка). Event-bus паттерн добавляет publish-subscribe: одно событие читают N сервисов независимо, у каждого своя позиция в потоке.
Когда применять
Используйте очередь, когда: producer не должен ждать consumer'а (long-running задачи); нужна устойчивость к падению consumer'а; одно действие порождает несколько асинхронных шагов (fan-out). Event-driven подход хорош, когда: вы строите микросервисы и не хотите hard-coupling через REST-вызовы между ними; нужен audit-trail всех бизнес-событий (event sourcing); разные команды владеют разными сервисами и не должны синхронно координироваться. Для маленьких систем (1-3 сервиса) очередь часто избыточна — синхронные вызовы проще. Введение event-bus имеет смысл от ~5 сервисов и больше.
Типичные ошибки
Грабли: путать команду (command) и событие (event) — команда говорит "сделай X", событие говорит "X произошло"; обрабатывать одно сообщение долго (минуты) — ack не отправляется, и брокер думает что consumer мёртв, переотправляет дубль; нет ограничения на размер очереди (растёт до диска и кладёт брокер); consumer не знает что делать с poison-message (всегда падает на одном сообщении) — нужен DLQ; eventual consistency недопонимают разработчики — UI показывает "ваш заказ создан" раньше, чем downstream сервис его увидел.