我正在使用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客户端实现了此方法。
还有另一种方法可以确保邮件通过吗?
答案 0 :(得分:1)
RabbitMQ使用Publisher Confirms以确保消息不会丢失,因此,如果您的Queue overflow behavior是reject-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)
然后我可以捕获异常并执行我需要做的重新发送/保存消息的操作。