1.当AcknowledgeMode=AUTO时
@Bean(value = "myRabbitListenerContainer")
public SimpleMessageListenerContainer simpleMessageListenerContainer(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
//设置消费的队列 , 队列可以是多个(参数是String的数组)
container.setQueueNames("Direct-Queue", "TTL-Failure-Queue");
//自动确认
container.setAcknowledgeMode(AcknowledgeMode.AUTO);
container.setMessageListener(new ChannelAwareMessageListener() {
@Override
//得到channel,可以对消息进行操作
public void onMessage(Message message, Channel channel) throws Exception {
System.out.println("消费方式一: 接收到的消息 message : " + message);
//抛出NullPointerException异常则重新入队列
//throw new NullPointerException("消息消费失败");
//当抛出的异常是AmqpRejectAndDontRequeueException异常的时候,则消息会被拒绝,且requeue=false
//throw new AmqpRejectAndDontRequeueException("消息消费失败");
//当抛出ImmediateAcknowledgeAmqpException异常,则消费者会被确认
throw new ImmediateAcknowledgeAmqpException("消息消费失败");
}
});
//后置处理器,接收到的消息都添加了Header请求头
container.setAfterReceivePostProcessors(new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
message.getMessageProperties().getHeaders().put("desc",10);
return message;
}
});
return container;
}
AcknowledgeMode.AUTO 根据方法的执行情况来决定是否确认还是拒绝(是否重新入queue)
- 如果消息成功被消费(成功的意思就是在消费的过程中没有抛出异常),则自动确认。
1)当抛出AmqpRejectAndDontRequeueException异常的时候,则消息会被拒绝,且requeue=false(不重新入队列)
2)当抛出ImmediateAcknowledgeAmqpException异常,则消费者会被确认
3)其他的异常,则消息会被拒绝,且requeue=true(如果此时只有一个消费者监听该队列,则有发生死循环的风险,多消费端也会造成资源的极大浪费,这个在开发过程中一定要避免的)。可以通过setDefaultRequeueRejected(默认是true)去设置,
2.RabbitAdmin申明异常
//设置忽略申明异常(避免创建重复队列以及创建异常的时候启动异常)
admin.setIgnoreDeclarationExceptions(true);