简体   繁体   English

将 Rebus 与 RabbitMQ 独占队列一起使用时出错

[英]Error when using Rebus with RabbitMQ exclusive queues

I'm getting the following exception when trying to respond to a RabbitMQ exclusive queue using Rebus.尝试使用 Rebus 响应 RabbitMQ 独占队列时出现以下异常。

-       e   {"Queue 'xxxx-xxxx' does not exist"}    Rebus.Exceptions.RebusApplicationException

+       InnerException  {"The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=405, text=\"RESOURCE_LOCKED - cannot obtain exclusive access to locked queue 'xxxx-xxxx' in vhost '/'. It could be originally declared on another connection or the exclusive property value does not match that of the original d...\", classId=50, methodId=10, cause="} System.Exception {RabbitMQ.Client.Exceptions.OperationInterruptedException}

The client declares the queue as exclusive and is able to successfully send the message to the server.客户端将队列声明为独占,并能够成功地将消息发送到服务器。 The server processes the message but throws the exception when sending the response.服务器处理消息,但在发送响应时抛出异常。

I can see in the Rebus source code (Rebus.RabbitMq.RabbitMqTransport.cs) that it attempts a model.QueueDeclarePassive(queueName) which throws the above exception.我可以在 Rebus 源代码 (Rebus.RabbitMq.RabbitMqTransport.cs) 中看到它尝试抛出上述异常的model.QueueDeclarePassive(queueName)

I found the following statement Here我在这里找到了以下语句

RabbitMQ extends the exclusivity to queue.declare (including passive declare), queue.bind, queue.unbind, queue.purge, queue.delete, basic.consume, and basic.get RabbitMQ 将排他性扩展到 queue.declare(包括被动声明)、queue.bind、queue.unbind、queue.purge、queue.delete、basic.consume 和 basic.get

Modifying the Rebus source to simply return true from the CheckQueueExistence method allows the response message to be sent.修改 Rebus 源以简单地从 CheckQueueExistence 方法返回 true 允许发送响应消息。 So my question is, is this an issue in Rebus with the use of the passive declare on an exclusive queue, is RabbitMQ blocking the call, or is there a fundamental concept I'm missing?所以我的问题是,这是在 Rebus 中使用独占队列上的被动声明的问题,是 RabbitMQ 阻塞了调用,还是我缺少一个基本概念?

The reason Rebus does the model.QueueDeclarePassive(queueName) thing, is because it tries to help you by verifying the existence of the destination queue before sending to it. Rebus 做model.QueueDeclarePassive(queueName)事情的原因是,它试图通过在发送到目标队列之前验证目标队列的存在来帮助您。

This is to avoid the situation where a sender goes这是为了避免发件人去的情况

using var bus = Configure.With(...)
    .(...)
    .Routing(r => r.TypeBased().Map<string>("does-not-exist"))
    .Start();

await bus.Send("I'M LOST 😱");

and the message is lost.并且消息丢失了。

The problem here is that RabbitMQ still uses a routing key to match the sent message to a binding pointing towards a queue, and if no matching binding exists (even when using the DIRECT exchange type) the message is simply routed to 0 queues, and thus it is lost.这里的问题是 RabbitMQ 仍然使用路由键将发送的消息与指向队列的绑定相匹配,如果不存在匹配的绑定(即使使用 DIRECT 交换类型),消息只是路由到 0 个队列,因此它丢失了。

If you submit a PR that makes it configurable whether to check that destination queues exist, then I'd be happy to (help you get it right and) accept it.如果您提交的 PR 可以配置是否检查目标队列是否存在,那么我很乐意(帮助您正确处理并)接受它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM