RabbitMQ 与 .NET

RabbitMQ with .NET

我一直在尝试创建一个 .NET RabbitMQ 消费者应用程序,但有些问题我无法通过 google 找到答案,所以我想我应该在这里问他们:

  1. 在规范中我发现 IConnection.CreateModel 返回的 IModel 实例不是线程安全的。这仅与调用 IModel.BasicPublish 方法有关(如果我理解正确,那么 BasicPublish/BasicAck/BasickNack/ets 不是线程安全的)还是这也包括注册消费者?换句话说,在 IModel.HandleBasicDeliver 周围使用相同的锁是否足够,或者我是否还必须使用相同的锁来包裹 IBasicConsumer.HandleBasicDelivery 的主体?

  2. IModel.BasicConsume 有一个布尔参数 noAck 我找不到任何帮助。将此参数设置为 True 是否意味着通过 IBasicConsumer.HandleBasicDeliver 传递消息时不会进行自动确认?如果我将其设置为 False,那么 RabbitMQ .Net 库将自动为所有收到的消息发送 Ack(s)?

  3. IBasicConsumer 方法调用是否序列化?换句话说,当 IBasicConsumer.HandleBasicDeliver?

  4. 已经在处理一条消息时,会调用 IBasicConsumer.HandleBasicDeliver

In other words is it sufficient to use the same lock around IModel.HandleBasicDeliver or do I also have to have use the same lock to wrap the body of IBasicConsumer.HandleBasicDelivery?

我通常会避免对 RabbitMQ .NET 客户端进行多线程访问 API。相反,我建议您 运行 在他们自己的进程中使用多个消费者。我已经在博客中详细讨论了这个 here。要回答您的问题,如果您 必须 允许多个线程访问该进程,我将锁定该函数,而不管您使用的是什么实现(IModel、IBasicConsumer 等)。记住; IModel 本身不是线程安全的,因此它的任何实现也不是。

If I set it to False then the RabbitMQ .Net library will automatically send Ack(s) for all received messages?

不,不会。在这种情况下,您需要手动发送确认。除非发送确认,否则消息将保留在队列中。

Are the IBasicConsumer methods calls serialized? In other words will IBasicConsumer.HandleBasicDeliver be called while a message is already being handled by IBasicConsumer.HandleBasicDeliver?

我假设您问的是调用是否连续调用,一个接一个调用,而不是作为将 C# 对象转换为标记的过程的序列化。在那种情况下,答案是肯定的,呼叫是按顺序处理的,不会重叠。消费者可以利用 QOS 属性 来确定他们一次阅读的消息数。即使 QOS 值很高,Consumer 仍然会按顺序处理消息。同样,请参阅上面的 link 以获取更多详细信息。