RabbitMQ EventingBasicConsumer并发性考虑

本文关键字:并发 EventingBasicConsumer RabbitMQ | 更新日期: 2023-09-27 18:03:54

我正在阅读。net API指南,它是非常好的信息,但我对RabbitMQ如何管理线程有点困惑。在并发考虑一节中,它声明每个连接都由单个后台线程备份。然后继续:

在应用程序向库注册的任何回调中,应用程序都可以看到线程模型的性质。这些回调函数包括:
  • 任何IBasicConsumer方法
  • IModel上的BasicReturn事件
  • IConnection, IModel等的各种关闭事件

我对此有点困惑。它们是否意味着每次调用HandleBasicDeliver时都会创建一个新线程?在这种情况下,接收到的消息将有尽可能多的线程,并发性由预取计数和消费者数量控制。

因此,如果我们考虑一个情况,我有一个 IConnection两个通道(IModel),每个通道的预取计数为一个一个 EventingBasicConsumer,我们将在应用程序中运行多少线程?

RabbitMQ EventingBasicConsumer并发性考虑

自从我第一次问这个问题以来,我已经对这个话题做了相当多的研究,所以我想我应该把它贴在这里,以防有人发现这个信息有用。

  • 对此持保留态度。以上是我对rabbit (c#)工作原理的理解。

    1. IConnection是一个实际的套接字连接。它将有一个线程轮询它。根据我读到的建议,每个应用程序使用一个连接,除非你有理由使用更多。

      • 使用多个连接并不一定意味着您有更好的容错能力,因为如果一个连接失败,通常会有一个问题,将导致所有连接失败。此外,在许多情况下,使用一个连接就足以处理来自网络的流量,根本没有必要拥有更多连接。http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2011-July/013771.htmlhttp://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2012-May/019873.html
    2. 在c#中通道不被认为是线程安全的,所以每个线程有一个通道不是一个坏主意,否则应该确保使用锁定机制。https://www.rabbitmq.com/dotnet-api-guide.html

    3. 根据我对阅读源代码的理解,handleBasicDeliver(我认为所有IModel调用)是在任务中运行的。考虑到这一点,拥有多个消费者确实会增加软件的并发性,因为如果一个消费者接收到消息并忙于处理它,另一个消费者可以自由地拾取消息并在不同的线程中执行它。此外,每个消费者必须在自己的通道上以最大化并发性,否则将保留消息顺序。但是,如果不欢迎这种并发性,请考虑使用单个通道来确保按照消息到达的顺序处理消息。注:第3点可能已经改变,通道顺序不再保留。我没有时间去探索新的变化,所以读完这篇文章,得出你自己的结论:https://github.com/rabbitmq/rabbitmq-dotnet-client/issues/251

我已经修改了我的答案,你做的研究看起来不错。

我使用Rabbitmq创建了一个应用程序,在这种情况下,我必须为IModel(通道)的数量共享相同的IConnection(连接)。这就是我们应该使用一个连接的方式,因为一个连接足以服务多个通道。

我曾经遇到的问题是,如果我为每个客户端创建一个连接,那么该队列的连接数量会继续增加,这将导致应用程序在一段时间后终止。

因此,除非必要,否则我们应该避免使用多个连接。如果可能的话,应该只对多个通道使用一个连接。

IConnection, IModel:

各种关闭事件

IModel即使down了IConnection仍然在那里。但是如果IConnection关闭了,那么那个连接下的所有IModel都会关闭。