Как устроена работа с RabbitMQ: отправитель, получатель, подписчики
Что проверяют
Понимаете ли вы модель AMQP: отправитель пишет не в очередь, а в обменник, а два потребителя одной очереди и две очереди на одном обменнике ведут себя по-разному. Следом спрашивают, как не потерять сообщение и что будет, если обработчик упал.
Как отвечать
- producer: публикует в exchange с routing key. Пустое имя означает default exchange, который кладёт сообщение в очередь с именем, равным ключу, отсюда иллюзия «пишу прямо в очередь»;
- exchange и binding:
directмаршрутизирует по точному ключу,topicпо шаблону (order.*.created,#),fanoutрассылает во все привязанные очереди,headersсмотрит на заголовки; - consumer: подписывается на очередь, брокер сам пушит сообщения. Потребители одной очереди конкурируют, каждое сообщение достаётся одному. Сколько неподтверждённых сообщений держит потребитель, задаёт prefetch через
BasicQos; - подписчики (pub/sub): у каждого своя очередь, привязанная к
fanoutилиtopic, поэтому одно событие получают все.
Надёжность складывается из трёх частей: durable очередь (для важных данных quorum queue, классическое зеркалирование в RabbitMQ 4 удалено), persistent сообщения и publisher confirms у отправителя. У потребителя autoAck: false и BasicAck только после успешной обработки. Ошибку отдают через BasicNack с requeue: false, и сообщение уходит в dead letter exchange, если он настроен у очереди.
В .NET учтите, что RabbitMQ.Client с 7-й версии полностью асинхронный: CreateConnectionAsync, CreateChannelAsync, IChannel вместо IModel, AsyncEventingBasicConsumer с событием ReceivedAsync. Соединение долгоживущее, одно на приложение, регистрируется синглтоном в DI, а канал не делят между потоками.
Где спотыкаются
Ставят autoAck: true и удивляются потерям: сообщение подтверждено при доставке, упавший обработчик его уже не вернёт.
Путают конкурирующих потребителей с подписчиками и ждут, что второй экземпляр сервиса тоже получит каждое событие.
Отвечают requeue: true на любую ошибку. Сообщение с битыми данными возвращается в очередь, тут же приходит снова и крутится бесконечно, забивая потребителя.