当邮件由于队列大小而被拒绝时,RabbitMQ不会发送失败

时间:2019-06-18 21:35:47

标签: java rabbitmq jms

我正在使用RMQ,它是将消息发布到RMQ的JMS客户端(这是我的要求,我不能使用其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溢出设置了一个策略:拒绝-发布,因此,如果超出限制,则在队列已满时,RMQ应该发送一个小消息,但我似乎不明白。

问题是-如何确定邮件是否被拒绝?我假设producer.send(msg)是同步的,并且如果未发布消息,则抛出异常,但是我没有任何异常,看起来一切都已发布。

JMS规范具有一个带有侦听器的send(msg,CompletionListener),该侦听器具有两个方法onCompletion和onException,但它看起来不像RMQ JMS客户端实现了此方法。

还有另一种方法可以确保邮件通过吗?

2 个答案:

答案 0 :(得分:1)

RabbitMQ使用Publisher Confirms以确保消息不会丢失,因此,如果您的Queue overflow behaviorreject-publish,则确认频道将获得nack。它也包含在许多AMQP客户端中。

但是在JMS客户端中,我已经检查了rabbitmq-jms-client中的代码,并且没有包含CompletionListener的发送实现。因此,如果您想享受可靠的发布,请使用AMQP客户端。

答案 1 :(得分:0)

我做了一些挖掘,CompletionListener是JMS 2.0的一部分,而RMQ仅实现JMS 1.1,这就是它不存在的原因。

但是看起来我可以做一些交易。我需要像这样更改代码:

CREATE ROLE readaccess;
ERROR:  cannot execute CREATE ROLE in a read-only transaction

如果队列未满,这将起作用,但是在拒绝消息后,将抛出异常:

原因:com.rabbitmq.client.ShutdownSignalException:频道错误;协议方法:#method(reply-code = 406,reply-text = PRECONDITION_FAILED-部分完成发送,class-id = 90,method-id = 20)

然后我可以捕获异常并执行我需要做的重新发送/保存消息的操作。