SpringMVC项目集成RabbitMQ
当新增了queue的x-message-ttl属性后,项目重启时报如下异常。我尝试着手动在RabbitMQ后台管理界面去重新创建这个queue,错误依旧如下。
这个异常目前不影响运行,请问什么原因导致,怎么解决?
| ERROR | 2020-02-04 21:25:08 | CachingConnectionFactory.java | shutdownCompleted | 292 | Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg ‘x-message-ttl’ for queue ‘ca_auth’ in vhost ‘/ca-auth’: received ‘30000’ but current is ‘30000’, class-id=50, method-id=10) |
| ERROR | 2020-02-04 21:25:08 | SimpleMessageListenerContainer.java | redeclareElementsIfNecessary | 975 | Failed to check/redeclare auto-delete queue(s). |
spring版本:3.2.11.RELEASE
spring-rabbit版本:1.4.6.RELEASE
rabbitMQ配置文件如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit-1.4.xsd">
<rabbit:connection-factory id="connectionFactory" virtual-host="/ca-auth" username="guest" password="guest" host="127.0.0.1" port="5672" publisher-confirms="true" publisher-returns="true"/>
<!-- 通过指定下面的admin信息 -->
<rabbit:admin id="connectAdmin" connection-factory="connectionFactory" />
<!--定义queue -->
<rabbit:queue name="ca_auth" durable="true" exclusive="false" declared-by="connectAdmin">
<rabbit:queue-arguments>
<entry key="x-message-ttl">
<value>30000</value>
</entry>
<entry key="x-dead-letter-exchange">
<value>dlx.file_to_file</value>
</entry>
<entry key="x-dead-letter-routing-key">
<value>ca</value>
</entry>
</rabbit:queue-arguments>
</rabbit:queue>
<rabbit:queue name="dlx.ca_auth" durable="true" exclusive="false" declared-by="connectAdmin">
<rabbit:queue-arguments>
<entry key="x-message-ttl">
<value>30000</value>
</entry>
</rabbit:queue-arguments>
</rabbit:queue>
<!--定义direct exchange -->
<rabbit:direct-exchange name="file_to_file" durable="true" declared-by="connectAdmin">
<rabbit:bindings>
<rabbit:binding queue="ca_auth" key="ca"/>
</rabbit:bindings>
</rabbit:direct-exchange>
<rabbit:direct-exchange name="dlx.file_to_file" durable="true" declared-by="connectAdmin">
<rabbit:bindings>
<rabbit:binding queue="dlx.ca_auth" key="ca"/>
</rabbit:bindings>
</rabbit:direct-exchange>
<!--定义rabbit template -->
<rabbit:template id="amqpTemplate" connection-factory="connectionFactory" exchange="file_to_file" confirm-callback="confirmCallBackListener" mandatory="true" return-callback="returnCallBackListener" retry-template="retryTemplate"/>
<!--定义receiver -->
<bean id="messageReceiver" class="com.cnpany.common.fadada.service.impl.AsynHandler"></bean>
<!--定义listener -->
<rabbit:listener-container connection-factory="connectionFactory" requeue-rejected="false">
<rabbit:listener queues="ca_auth" ref="messageReceiver" />
</rabbit:listener-container>
<bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate">
<property name="retryPolicy">
<bean class="org.springframework.retry.policy.SimpleRetryPolicy">
<property name="maxAttempts" value="3"/>
</bean>
</property>
</bean>
</beans>
最终解决
根据青山老师给出的提示,具体解决如下
1、当在RabbitMQ后台管理界面去对Queue新增x-message-ttl时需要选择取值类型,此时取值不能选择String,否则提示属性可接受类型异常。注意:必须选择Number。
2、由此可以想到,xml配置文件中的x-message-ttl必须是数值类型。再由xsd配置规则,value标签默认取值类型为String,需要指定类型完成类型转换。
配置文件中关于x-message-ttl的配置需要增加type=“java.lang.Long”
<rabbit:queue-arguments>
<entry key="x-message-ttl">
<value type="java.lang.Long">30000</value>
</entry>
</rabbit:queue-arguments>
明确什么情况下报406的错误:
https://www.rabbitmq.com/queues.html
When the existing queue attributes are not the same as those in the declaration a channel-level exception with code 406 (PRECONDITION_FAILED) will be raised.
当尝试声明一个队列时,已经存在一个队列,并且属性参数不一致的时候,会报406的错误。如果属性参数一致,直接返回OK(所以相同属性的队列时可以重复声明的)。
知道了问题的原因,可以尝试的解决办法:
1、在管理界面删除队列,由Spring配置文件直接创建。
2、或者确定管理界面创建的队列与Spring配置的队列是否一致。