RabbitMQ не вызывает ошибки отправки, когда сообщения отклоняются из-за размера очереди - PullRequest
0 голосов
/ 19 июня 2019

Я использую RMQ и его JMS-клиент для публикации сообщений в RMQ (это требование, которое у меня есть, я не могу использовать их Java-клиент вместо JMS-клиента).

Итак, в основном я делаю это:

        RMQConnectionFactory factory = new RMQConnectionFactory() ;
        factory.setUsername(props.getProperty("rmq.username"));
        factory.setPassword(props.getProperty("rmq.password"));
        factory.setHost(props.getProperty("rmq.host"));
        factory.setVirtualHost(props.getProperty("rmq.virtualHost"));
        factory.setPort(Integer.parseInt(props.getProperty("rmq.port")));

        Connection connection = factory.createConnection();
        connection.start();
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        String queueName = managerProps.getProperty("rmq.queue.name");
        Queue queue = session.createQueue(queueName);
        producer = session.createProducer(queue);

        TextMessage msg = session.createTextMessage(text);
        msg.setText(text);
        producer.send(msg);

У меня есть политика, настроенная на переполнение RMQ: reject-publish, поэтому, если она превышает лимит, RMQ должен отправлять nack, когдаочередь переполнена, но я, кажется, не понимаю.

Вопрос - как определить, было ли сообщение отклонено?Я предполагаю, что продюсер.send (msg) является синхронным и выдает исключение, если сообщение не публикуется, но я не получаю никаких исключений, просто похоже, что все было опубликовано.

В спецификации JMS есть функция send (msg, CompletionListener) со слушателем с двумя методами onCompletion и onException, но не похоже, что JMS-клиент RMQ реализовал этот метод.

Есть ли другой способ убедиться, что сообщение прошло через него?

Ответы [ 2 ]

1 голос
/ 19 июня 2019

RabbitMQ использует Издатель подтверждает , чтобы гарантировать, что сообщение не потеряно, поэтому, если ваше Поведение при переполнении очереди равно reject-publish, канал подтверждения получит nack.Он также содержится во многих клиентах AMQP.

Но в клиенте JMS я проверил код в rabbitmq-jms-client , и никакая реализация отправки не содержит CompletionListener.Так что, если вы хотите наслаждаться надежной публикацией, пожалуйста, используйте клиент AMQP.

0 голосов
/ 19 июня 2019

Я немного покопался, CompletionListener является частью JMS 2.0, а RMQ реализует только JMS 1.1, поэтому его там нет.

Но похоже, что я могу что-то сделать с транзакциями.Мне нужно изменить код следующим образом:

    RMQConnectionFactory factory = new RMQConnectionFactory() ;
    // ... skipping the code here
    connection.start();
    // set session to be transacted 
    session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
    String queueName = managerProps.getProperty("rmq.queue.name");
    Queue queue = session.createQueue(queueName);
    producer = session.createProducer(queue);

    TextMessage msg = session.createTextMessage(text);
    msg.setText(text);
    producer.send(msg);
    // commit transaction
    session.commit();

Это будет работать, если очередь не заполнена, но выдаст исключение после отклоненного сообщения с этим:

Причина:com.rabbitmq.client.ShutdownSignalException: ошибка канала;Метод протокола: #method (код ответа = 406, текст ответа = PRECONDITION_FAILED - частичное завершение передачи, идентификатор класса = 90, идентификатор метода = 20)

Затем я могу поймать исключение и сделать то, что янужно сделать, чтобы повторно отправить / сохранить сообщение.

...