如何防止消费被拒绝的消息

时间:2017-06-23 05:39:57

标签: spring-amqp

我有一个消费者使用队列中的消息(手动确认),然后通过调用Basic.Nack()或Basic.reject()方法将其拒绝。之后,消费者仍然会使用被拒绝的消息。

如何阻止同一个消费者使用被拒绝的消息?相反,被拒绝的消息应该重新传递给不同的消费者吗?

更新

邮件侦听器委托

public class MessageListenerDelegate implements ChannelAwareMessageListener {
private MessageListener messageListener;

@Override
public void onMessage(Message message, Channel channel) throws Exception {

}

// setter and getter for MessageListener
....

}

public interface MessageListener {
void onMessage(MessageResourceHolder holder) throws Exception;

}

在应用启动期间设置并行使用者并启动消费者

 
public void listen(String queueName, MessageListener messageListener) {
    SimpleMessageListenerContainer listener = new SimpleMessageListenerContainer(connectionFactory);
    listener.setMessageListener(new MessageListenerAdapter(new MessageListenerDelegate(messageListener)));
    listener.addQueueNames(queueName);
    listener.setConcurrentConsumers(5);
    listener.setAcknowledgeMode(AcknowledgeMode.MANUAL);
    listener.start();
}

现在侦听队列,然后调用Basic.Nack()拒绝消费消息


listen(queueName, new MessageListener() {

            @Override
            public void onMessage(MessageResourceHolder holder) throws IOException {
                    holder.getChannel().basicNack(holder.getMessageProperties().getDeliveryTag(), false, true);

            }
        }); 

消费者在许多线程中运行,因此它总是消耗来自队列的消息,包括被拒绝的消息

1 个答案:

答案 0 :(得分:0)

  

basicNack(holder.getMessageProperties().getDeliveryTag(), false, true);

通过将最后一个参数设置为true,您明确告诉RabbitMQ重新排队该消息。

/**
 * Reject one or several received messages.
 *
 * Supply the <code>deliveryTag</code> from the {@link com.rabbitmq.client.AMQP.Basic.GetOk}
 * or {@link com.rabbitmq.client.AMQP.Basic.GetOk} method containing the message to be rejected.
 * @see com.rabbitmq.client.AMQP.Basic.Nack
 * @param deliveryTag the tag from the received {@link com.rabbitmq.client.AMQP.Basic.GetOk} or {@link com.rabbitmq.client.AMQP.Basic.Deliver}
 * @param multiple true to reject all messages up to and including
 * the supplied delivery tag; false to reject just the supplied
 * delivery tag.
 * @param requeue true if the rejected message(s) should be requeued rather
 * than discarded/dead-lettered
 * @throws java.io.IOException if an error is encountered
 */
void basicNack(long deliveryTag, boolean multiple, boolean requeue)
        throws IOException;