rabbitmq交换机类型不同导致异常
今天收到预生产环境测试人员的消息说项目启动失败,看了一下错误是rabbitmq
的队列监听抛出找不到该队列,没有道理,逻辑上已经经过了测试环境的测试没有理由犯这么低级的错误。吓得我赶紧看去看了一下预生产环境的apollo
配置信息(我们使用的mq
厂商随环境的不同可能不同),配置信息也是对的;赶紧再次核对一下错误日志,发启动时创建交换机还有另外的报错:
1 | 2021-04-14 16:58:23.014 [AMQP Connection 192.168.2.16:5672] ERROR o.s.a.r.c.CachingConnectionFactory-Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'type' for exchange 'xxxxx' in vhost '/': received 'topic' but current is 'fanout', class-id=40, method-id=10) |
大概的意思是已经存在该名称为fanout
类型交换机不允许改变为topic
类型交换机。
为什么会导致这个问题?
由于数据之间的解耦传输是由两个团队处理,A团队负责发送消息,B团队负责接收消息。沟通中没有交流清楚细节导致。
A团队创建
fanout
类型且名称为PUSH_INFO_EXCHANGE
的交换机B团队创建
topic
类型且名称为PUSH_INFO_EXCHANGE
的交换机,routeKey
为空串,队列名称为RECEIVE_INFO_QUEUE
。
这就导致,AB团队同时提测,如果先启动了B服务,则rabbitmq
创建了一个名为PUSH_INFO_EXCHANGE
类型为广播的交换机,并绑定在RECEIVE_INFO_QUEUE
队列上;这时如果启动A服务,在RabbitMq
中,一旦创建了交换机是不允许改变的,所以A服务的创建是不会成功,但有意思的是,A服务推送数据时,是可以找到这个交换机,且通过空串路由键B服务可以接收到相应的数据,这样也就是导致在测试环境中没有发现这个异常的原因。而在预生产环境中,严格按照先启动A服务后再启动B服务进行就抛出了开头的异常信息。
不要问为什么AB团队都创建了同名的交换机,如果这时A的业务场景有需要将某个队列绑定到这个交换机呢?