我们在骆驼版2.16.0中使用了rabbitMQ(v3.5.5)InOut功能,并设置了如下流程:
制片人 - > route1 - > rabbitMQ - > route2 - > rabbitMQ - > route3 - >服务bean
服务bean将返回一个响应,调用者可以选择是否感兴趣。它设置为这样,以便路由可以重用于异步和同步处理,其中调用者可以只指示是否它通过将交换模式设置为InOnly或InOut来关注响应。
来自端点的rabbitMQ配置如下:
from( "direct:route1" )
.to( "rabbitmq://localhost:5672/testExchange?exchangeType=topic&autoDelete=false&declare=false" );
from( "rabbitmq://localhost:5672/testExchange?queue=queue.test.exchange&exchangeType=topic&autoDelete=false" +
"&deadLetterExchangeType=direct&deadLetterExchange=deadLetterTestExchange" +
"&deadLetterQueue=deadletter.test.exchange&deadLetterRoutingKey=#" +
"&autoAck=false&transferException=true" )
.throwException( new RuntimeException( "test exception" ) );
我们设置了autoAck = false,以便对于InOnly交换,如果有任何异常,该消息将被拒绝并推送到deadletter queue。
然而,对于InOut交换,如果抛出异常,假设我们有autoAck = false且transferException = true,则原始消息将永远不会在rabbitMQ上被确认,即使异常传播回调用者以进行处理。如果重新启动服务器,应用程序将尝试重新处理该消息。
在InExut交换失败并且transferException = true的情况下,是否有人知道为原始邮件发送basicAck或basicReject是否会违反任何最佳做法?
在将异常转回生产者之后,将完成basicAck / Reject。
对于我们的用例,basicAck似乎更合适,因为调用者能够处理异常,因此不需要也将消息传播到deadletter队列。