Ответы пользователя по тегу RabbitMQ
  • Как в RabbitMQ обработать все сообщения а затем удалить очередь и закрыть соединение?

    @yarkin
    Я не из мира PHP, но полагаю что можно попробовать basic_get вместо basic_consume, или попробовать опцию $nowait=true
    Ответ написан
    Комментировать
  • Как избавиться от ошибки "no free channel ids" в rabbitmq?

    @yarkin
    По PHP возможно не подскажу, но всё же в таких ситуациях желательно публиковать и пример кода. По всей видимости, открывается канал (channel) на каждую публикацию сообщения, чего делать не стоит. Каналы нужны для параллельной работы через одно TCP подключение, так как AMQP протокол по своей натуре синхронный (следующую команду нельзя послать, если ожидается ответ от предыдущей). Если через один канал скорость публикации сообщений с подтверждением не устраивает, то можно:
    • открыть несколько параллельных каналов,
    • или использовать пакетную отправку, когда подтверждение приходит на каждые N запросов.
    Ответ написан
  • Как переслать сообщения из одной очереди в другую?

    @yarkin
    1) Если "не получается обработать" это котролируемый процесс, то можно использовать команды basic.reject или basic.nack с флагом requeue=true, чтобы сообщение попало обратно в рабочую очередь.
    2) Можно использовать тот же механизм DLX на очереди с ошибками вместе, например, с TTL. Сообщение попадает в очередь ошибок, лежит там, папример, 10 минут, а потом обратно перекидывается в рабочую очередь.
    Ответ написан
    Комментировать
  • Есть ли аналог заголовков в RabbitMQ?

    @yarkin
    Протокол AMQP поддерживает добавление дополнительных заголовков к сообщению (похоже на HTTP), тут описана структура сообщения, смотрите Headers там. Но по возможности не стоит добавлять туда пользовательские данные, лучше всё-таки добавить в сообщение:
    • RabbitMQ тратит ресурсы на парсинг и хранение этих данных,
    • Легче в будущем будет переходить на другую технологию, в которой не будет такой фичи.
    Ответ написан
    Комментировать
  • Как не потерять данные из очереди RabbitMQ, если они только в памяти, при остановке?

    @yarkin
    Если сообщения не persistent, то единственный случай, когда RabbitMQ сохранит их на диск это нехватка оперативной памяти (и вроде бы не все сообщения, а только часть). Но даже если сообщение содержит persistent=on RMQ может хранить его копию в памяти как кэш. Так же RMQ не записывает сообщения на диск моментально, а держит сколько-то миллисекунд только в памяти, чтобы можно было аггрегировать запись.
    Ответ написан
  • Как проверить publisher`а в RabbitMQ?

    @yarkin
    Нет, в этих протоколах такого не предусмотрено. Я не знаю другого варианта, кроме как через management плагин.
    Ответ написан
  • Нормально ли создавать множество очередей на один и тот же ивент?

    @yarkin
    Да, нормально, очередь запускается для потребителя (пула потребителей). Для публикующей стороны создаются обменники.
    Ответ написан
    Комментировать
  • Почему низкая скорость публикации сообщений в очередь RabbitMQ?

    @yarkin
    Всё зависит от того какие параметры отказоустойчивости применяются. В RabbitMQ работа одного канала (channel) синхронна, нет параллельной обработки команд. Если есть ожидание подтверждения от сервера и требование записи данных на диск (а RabbitMQ, если ничего не изменилось за последние годы, аггрегирует запись в батчи, чтобы уменишить кол-во IOPS на диск, то есть какое-то ожидание), то это увеличивает временя одной команды. Плюс сетевое RTT.
    Если надо посылать как можно больше - открывайте много каналов. Ради интереса попробуйте потестировать на простой очереди в памяти (это должно уменьшить время обработки одной команды).
    Ответ написан
    4 комментария
  • Как организовать RabbitMQ очередь для нескольких микросервисных приложений?

    @yarkin
    В AMQP есть механизмы подтверджения клиентом обработки сообщения (basic.ack), посмотрите вот тут вот тут
    Ответ написан
    Комментировать
  • Почему через celery (rabbit и пр. очереди сообщений) не рекомендуется передавать большие массивы данных (как аудио или видео)?

    @yarkin
    Потому-что брокеры сообщений не сильно хороши в таком. В целом такое можно сделать (предварительно настроив брокер), но производительность системы упадёт на столько, что следующим Вашим вопросом будет: "Почему так тормозит". От брокеров обычно ждут минимальный отклик, поэтому стараются сократить сообщения до минимально возможного.
    Ответ написан
    2 комментария
  • Что использовать для реализации EDA в микросервисной архитектуре?

    @yarkin
    RabbitMQ это про очереди, если у вас есть очередь задач, то не думаю, что захотите чтобы все воркеры выполняли одно и тоже действие. Если нужно, чтобы каждый сервис получал копию сообщения, они должны иметь независимые очереди, которые могут быть подписаны на один эксчендж.
    Если у вас может быть по N инстансов одного сервиса, то все N подписываются на одну и ту же очередь (иначе см. выше что будет), но каждый сервис должен иметь свою очередь.
    Почитайте базовые мануалы по RabbitMQ - https://www.rabbitmq.com/getstarted.html - там много полезного найдёте (на хабре есть переводы на русский, если надо)

    Например, для простоты возмём что эксчендж всего один - events. Есть два сервиса - S1 и S2. У каждого из них по 3 инстанса. Сервисы хотят получать все сообщения которые публикуются в events.
    Получаем (допусти ещё ничего нет):
    - создаём эксчендж events (лучше до запуска всего) с типом fanout
    - первый инстанс S1 при запуске создаёт очередь - events-s1; создаёт биндинг этой очереди на эксчендж events; подписывается на эту очередь
    - второй и третий инстансы S1 при запуске видят, что очередь есть и просто подписываться на неё
    - всё тоже самое повторяется для S2

    При росте сервисов, одного эксченджа может не очень хватить, тогда одна очередь может имеет более одного биндинга к нужным ей эксченджам. Или тип эксченджа можно поменять на topic и управлять тем кто получит сообщения уже через ключи биндингов и заголовки сообщений, а не имена эксченджей.
    Ответ написан
    Комментировать
  • Как правильно повторно выполнять неудачные задачи?

    @yarkin
    RabbitMQ вряд ли может знать, когда какой-то внешний сайт становится доступным, самый простой вариант здесь - подождать и попробовать ещё раз.
    Силами RabbitMQ это можно сделать с помощью расширения Dead Letter Exchanges:
    * На основную очередь - Q1 - вешается политика/устанавливается опция dead-letter-exchange=Q2
    * На Q2 вешается политика/опция dead-letter-exchange=Q1 + message-ttl=<время между повторами>
    Ответ написан
    2 комментария
  • RabbitMQ: вопрос по consumer-у?

    @yarkin
    Куда происходит публикация сообщения, в обменник? Кто создаёт очередь и биндинг на обменник? Может ли такое случиться, что если очередь и биндинг создаёт консьюмер, то в момент их создания обменника ещё не существует и происходит ошибка, которая игнорируется? Раз есть management плагин в контейнере, можно посмотреть состояние системы в момент, когда сообщения не получаются консьюмером: есть ли очередь, обменник, бингдинг между ними, консьюмер очереди.
    Но тоже не забывайте, что если в первую очередь стартует паблишер, а потом консьюмер, то при отсутсвующих очередях можно потерять сообщения. В идеале создавать всю инфраструктуру обменников и очередей должен какой-то скрипт инициализации, до старта основных приложений (что-то схожее с запускам миграции БД). Но такое так же можно сделать с помощью самого RabbitMQ.
    Ответ написан
    2 комментария
  • Как правильно работать с очередями RabbitMQ?

    @yarkin
    Если эти запросы на gateway не требуют ответа от микросервисов, чтобы сформировать ответ пользователю (асинхронные), то RabbitMQ подойдёт хорошо. Ваше решение будет работать нормально (очередь на сервис), но посмотрите, если её ещё можно разделить на разные области внутри сервиса, или если ещё уже - по очереди на конкретный метод. "Сужение" очереди даст возможность далее разделить микросервис на нескоклько, а так же даст больше для мониторинга (детальней будет видно каких типов запросов в очереди больше и т.п.)
    Ответ написан
    Комментировать
  • Большие ли задержки в очередях сообщений?

    @yarkin
    Если говорить только о задержке внутри RabbitMQ при работе только в памяти, то не думаю, что она превысит пары миллисекунд на незагруженной системе. В RabbitMQ если очередь не-durable, сообщение не имеет флага persistent и нет memory pressure (хватает памяти), то обработка происходит чисто в памяти.
    Но, если всё что нужно, это передать данные от одного сервиса к другому, то поднимать инстанс RabbitMQ может быть очень накладно. Попробуйте для начала вызывать второй сервис из первого с передачей данных напрямую. Другим вариантом может быть простой message bus (например, NATS), который не имеет очередей и не хранит данные, а отправляет сразу (или дропает сообщение, если нет подписчиков).
    Ответ написан
  • Может ли rabbitmq вызывать события?

    @yarkin
    RabbitMQ это брокер сообщений, его задача это получить/сохранить/отправить, он не вникает в суть таких сообщений, всё остальное на стороне бизнес-логики. Если задача отправляется в очередь в сам RabbitMQ, то уведомлять о её добавлении смысла нет, потому-что если кто-то подписан на очередь с задачами, RabbitMQ сразу отправить ему сообщение с задачей. Уведомления о фазах обработки сообщений должна уже отсылать сама бизнес-логика.
    (В RabbitMQ есть возможность отсылать все внутренние события в заданную очередь, но я не думаю, что это то, что Вы ищите, это больше для отладки, когда непонятно, что происходит.)
    Ответ написан
    Комментировать
  • RabbitMQ: как правильно выполнять тяжелые задачи?

    @yarkin
    Была подобная проблема, сишный клиент в один поток не умел нормально в heartbeat. При отключении heartbeat'ов на уровне AMQP протокола были проблемы с "зависшими клиентами" на стороне RabbitMQ, когда приложение выходило непредвиденно. Настройка TCP keepalive помогла решить данную проблему.
    Не знаю точно как работает современный php, но, если есть возможность держать отдельный поток для поддержания AMQP коннекта с включённым heartbeat'ом, то это будет лучше, чем через TCP keepalive. Отсылать ack обратно лучше всё же после завершения обработки задачи.
    Ответ написан
    Комментировать
  • RabbitMQ какой тип exchange выбрать для сообщений?

    @yarkin
    Многое зависит от остальной архитектуры. Например, что такое "userX" со стороны RabbitMQ? Это прямое подключение клиента к RabbitMQ или клиент подключается через какую-то бизнес-логику (сколько инстансов)?
    Держит ли клиент постоянное подключеие до БЛ/RabbitMQ или делает периодические запросы к ним? Храняться ли данные в СУБД? Какие требования к отклику? Сколько событий/заявок в секунду/минуту ожидается?
    Ответ написан
    4 комментария
  • Почему не могу запустить RabbitMQ Server?

    @yarkin
    Как могу судить из логов, Erlang не нашёл функцию crypto:macN/5, которая была добавлена в версию Erlang/OTP 22.1. Так что тут либо не установлен модуль crypto в систему, либо версия Erlang/OTP меньше чем 22.1
    Ответ написан
    Комментировать
  • Как организовать очередь сообщений так, что бы каждое след. сообщение передавалось только после того, как обработано предыдущее?

    @yarkin
    Из текста не до конца понятно, Вы хотите, чтобы была очередь или sender должен выполняться каждый раз для нового сообщения? Если очередь, то обрабатывать сообщения по одному можно, но только если получатель один. В протоколе AMQP можно вручную получать сообщения по одному - basic_get, или выставить количество неподтвержденных сообщений в 1 и подтверждать обработку каждого.
    Ответ написан
    Комментировать