故事
这两天一直在做毕业设计,在搭建项目框架的时候遇到了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());
}
}
版权声明:本文为qq_40432886原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。