rabbitMq消息重复发送,重复ack原因
故事
这两天一直在做毕业设计,在搭建项目框架的时候遇到了rabbitMq相关的东西,然后之前自己有大致学习过,现在全部忘记的一干二净,然后就是基础不牢地动山摇,好好打基础吧
程序报错
Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - unknown delivery tag 1, class-id=60, method-id=80)
大概就是说,Channel这玩意已经关闭了,没了,为什么没了呢,开始我也一直想不明白,我明明在yml文件中配置了手动ack,yml像这样。
pring: rabbitmq: addresses: xxx.xxx.xxx.xxx:xxxx username: admin password: admin publisher-confirms: true publisher-returns: true #默认虚拟主机 virtual-host: / #连接超时实践 connection-timeout: 10000 publisher-confirm-type: correlated template: mandatory: true retry: max-attempts: 5 #最大重试次数 max-interval: 10000 #最大重试时间 #消费端配置 listener: type: direct direct: max-concurrency: 50 concurrency: 10 acknowledge-mode: manual #签收设置 retry: enabled: true initial-interval: 50000 prefetch: 1 #限流
然后百度了很多,emmmm全是复制粘贴,关键是还解决不了我的问题。造成这个错误会有啥结果呢?
错误结果
生产者所投递的消息,虽然只是投递了一次,但是消费者会进行两次或者多次应答,然后造成消息被被两次以上重复投递
错误原因
进行多次ack,重复ack所造成
出现原因
应为在rabbitmqConf中使用了序列化设置,造成了设置manual失效。原来的配置类如下:
出现错误的配置类
@Configuration public class RabbitMqConfig implements RabbitListenerConfigurer { ... ... @Override public void configureRabbitListeners(RabbitListenerEndpointRegistrar rabbitListenerEndpointRegistrar) { rabbitListenerEndpointRegistrar.setMessageHandlerMethodFactory(messageHandlerMethodFactory()); } @Bean MessageHandlerMethodFactory messageHandlerMethodFactory(){ DefaultMessageHandlerMethodFactory messageHandlerMethodFactory = new DefaultMessageHandlerMethodFactory(); messageHandlerMethodFactory.setMessageConverter(mappingJackson2MessageConverter()); return messageHandlerMethodFactory; } @Bean public MappingJackson2MessageConverter mappingJackson2MessageConverter(){ return new MappingJackson2MessageConverter();
处理
在配置类的SimpleRabbitListenerContainerFactory中增加
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
到此问题得以解决。修改后的配置文件为
/** * @author WangShilei * @date 2020/11/13-13:34 **/ @Configuration @Slf4j public class RabbitMqConfig { ... ... @Bean public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, MessageConverter messageConverter) { RabbitTemplate template = new RabbitTemplate(connectionFactory); template.setMessageConverter(messageConverter); return template; } @Bean public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory, MessageConverter messageConverter) { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setAcknowledgeMode(AcknowledgeMode.MANUAL); factory.setConnectionFactory(connectionFactory); factory.setMessageConverter(messageConverter); return factory; } @Bean public MessageConverter messageConverter() { return new ContentTypeDelegatingMessageConverter(new Jackson2JsonMessageConverter()); } }
上一篇:
IDEA上Java项目控制台中文乱码