【问题标题】:RabbitMQ with .NET带有 .NET 的 RabbitMQ
【发布时间】:2015-01-05 16:22:42
【问题描述】:

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

  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 是否会在 IBasicConsumer.HandleBasicDeliver 已在处理消息时被调用?

【问题讨论】:

    标签: .net multithreading rabbitmq


    【解决方案1】:

    换句话说,在 IModel.HandleBasicDeliver 周围使用相同的锁就足够了,还是我还必须使用相同的锁来包裹 IBasicConsumer.HandleBasicDelivery 的主体?

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

    如果我将其设置为 False,那么 RabbitMQ .Net 库将自动为所有收到的消息发送 Ack(s)?

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

    IBasicConsumer 方法调用是否已序列化?换句话说,IBasicConsumer.HandleBasicDeliver 已经在处理消息时是否会调用 IBasicConsumer.HandleBasicDeliver?

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

    【讨论】:

    • 谢谢。我将为 BasicPublish 使用单独的频道 (IModel),并在另一个频道上设置消费者。
    • 没问题。是的,将每个关注点限制在单独的渠道中是个好主意。通道只是进入 TCP 连接的逻辑管道,不会增加太多开销。
    猜你喜欢
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多