最近在看springboot 整合消息中间件的部分,
之前对于消息中间价的消息回调机制不是太清楚,这次做了一次测试
下面是测试代码
@RabbitListener(queues = {"queue_1"})
public void msgListener(Message message, Channel channel) throws IOException {
//System.out.println("message:" + message);
try {
//int i = 1/0; //测试接收消息抛出异常情况
//消息手动确认
//如果配置文件中配置了acknowledge-mode: none、auto,在这里消费时会报错,因为队列中的消息已经删除了(Channel shutdown: channel error, unknown delivery tag )
//如果配置文件中配置了acknowledge-mode: manual,正常消费
//basicAck:消费者回调broker已经收到消息;参数:long deliveryTag, boolean multiple
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
System.out.println("消费消息确认:" + message.getMessageProperties().getConsumerQueue() + ",DeliveryTag:" + message.getMessageProperties().getDeliveryTag() + ",接收到了回调方法");
} catch (Exception e) {
System.out.println("尝试重发:" + message.getMessageProperties().getConsumerQueue() + ":" + message.getMessageProperties().getDeliveryTag());
//若acknowledge-mode= manual, requeue=true,会一直重试,DeliveryTag会持续+1,配置文件的重试配置不起作用,
//若acknowledge-mode= auto, requeue=true,会一直重试,DeliveryTag不变,配置文件的重试配置不起作用,
//若acknowledge-mode= none, requeue=true,消息被自动确认
//若requeue=false,队列中消息会被丢弃
//basicNack:消费者回调broker已经接收消息,但没确认;参数:long deliveryTag, boolean multiple, boolean requeue
//channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
//与basicNack 相同
//basicReject:消费者拒绝消息,不确认;参数:long deliveryTag, boolean requeue
channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
}
}
-
acknowledge-mode:none, auto, manual
none: 自动确认;auto:根据情况;manual:手动确认 -
deliveryTag:消息的唯一表示(在同一个队列内)
-
multiple:批量 (手动模式下)
-
requeue:重回队列(requeue =true 重回队列,false 丢弃),建议requeue 设置为false,
消息处理发生异常,除非网络方面的原因,否则处理多次也是失败;根据自己的业务处理失败消息,比如存储到数据库或缓存中,或者报警;网络方面的异常建议开启重试机制 -
springboot中默认重试机制是关闭的,以下添加重试机制的组件
@Configuration
public class MyRabbitmqConfig {
@Bean
public SimpleRabbitListenerContainerFactory myFactory(
SimpleRabbitListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory =
new SimpleRabbitListenerContainerFactory();
configurer.configure(factory, connectionFactory);
factory.setRetryTemplate(new RetryTemplate());
return factory;
}
}
- 配置文件(.yml)
spring:
rabbitmq:
host: localhost
username: guest
password: guest
virtual-host: /
listener:
simple:
acknowledge-mode: manual // 开启手动确认
retry:
enabled: true // 开启重试
max-attempts: 3 //最大重试次数
initial-interval: 2000ms //重试间隔时间