我在Spring启动应用程序中使用Camel并与RabbitMQ集成,但遇到了奇怪的行为。
我的应用程序具有Restful端点,可将http请求转换为RabbitMQ消息并将其发布到预定义的交换。有一个单独的消费者应用程序,它监听队列并处理消息。
我故意输入了一个不正确的rabbitmq交换名称(invalidxchangename)来检查应用程序是否会在交换机不存在的情况下失败,但是驼峰上下文启动时没有错误,当我发送第一个请求时是不报告任何错误。由于没有匹配的RabbitMQ交换,此消息会丢失。当我提交第二个请求时,我收到以下异常,这是我在路由启动时预期的。
com.rabbitmq.client.AlreadyClosedException: channel is already closed due to channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'invalidxchangename' in vhost
编辑: 我尝试了一个更简单的例子来展示Camel中的问题。
我创建了一条简单的路线如下:
from("file:in?fileName=in.txt").log(LoggingLevel.DEBUG, "in here!").to("rabbitmq://localhost:5762/invalidexchange?declare=false");
其中有一个名为validexchange的现有RabbitMQ交换(因此我故意在RabbitMQ uri中输入了一个错字)。我希望骆驼路由在启动时失败,因为交换不存在,或者甚至是第一次尝试处理新的in.txt文件。
我在日志中实际看到的是,在启动时它报告没有错误,并且仅在第二次调用路由时报告错误。
2015-03-11 16:17:04.356 INFO 9756 : ID-SBMELW7W-06220-59960-1426051020468-0-2 >>> (route2) from(file://in?fileName=in.txt) --> log[in here!] <<< Pattern:InOnly, Headers:...
2015-03-11 16:17:04.360 INFO 9756 : ID-SBMELW7W-06220-59960-1426051020468-0-2 >>> (route2) log[in here!] --> rabbitmq://localhost:5762/customerchannel.exchang?declare=false <<< Pattern:InOnly, Headers:...
2015-03-11 16:17:45.073 INFO 9756 : ID-SBMELW7W-06220-59960-1426051020468-0-4 >>> (route2) from(file://in?fileName=in.txt) --> log[in here!] <<< Pattern:InOnly, Headers: ...
2015-03-11 16:17:45.079 INFO 9756 : ID-SBMELW7W-06220-59960-1426051020468-0-4 >>> (route2) log[in here!] --> rabbitmq://localhost:5762/customerchannel.exchang?declare=false <<< Pattern:InOnly, Headers:...
2015-03-11 16:17:45.092 ERROR 9756 : Failed delivery for (MessageId: ID-SBMELW7W-06220-59960-1426051020468-0-3 on ExchangeId: ID-SBMELW7W-06220-59960-1426051020468-0-4). Exhausted after delivery attempt: 1 caught: com.rabbitmq.client.AlreadyClosedException: channel is already closed due to channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'customerchannel.exchang' in vhost '/', class-id=60, method-id=40)
答案 0 :(得分:0)
看起来第一个请求导致错误,该错误会关闭连接并记录原因,当您第二次尝试使用该频道时,它会返回AlreadyClosedException
并显示导致该消息的消息在第一次通话中关闭的频道。
您可以通过尝试将第二条消息发布到同一通道中的其他交换名称并检查错误中的哪个交换来测试此操作。例如。将第二条消息发布到invalidxchangename2
,您仍应将invalidxchangename
视为错误中的交换。
要修复,如果发生错误,您应该在发布和重新建立连接时处理发布结果。
答案 1 :(得分:0)
如果您想确保邮件已传递到RabbitMQ队列,则必须使用发布者确认:https://www.rabbitmq.com/confirms.html
您可以发布消息并不意味着消息将到达队列。你可以去一个邮箱里面写一封信,但是在你把那封信留在那里和一个邮递员拿走之间,很多事情都可能发生,例如邮箱着火等等。