RabbitMQ EventingBasicConsumer并发性考虑
本文关键字:并发 EventingBasicConsumer RabbitMQ | 更新日期: 2023-09-27 18:03:54
我正在阅读。net API指南,它是非常好的信息,但我对RabbitMQ如何管理线程有点困惑。在并发考虑一节中,它声明每个连接都由单个后台线程备份。然后继续:
在应用程序向库注册的任何回调中,应用程序都可以看到线程模型的性质。这些回调函数包括:
- 任何IBasicConsumer方法
- IModel上的BasicReturn事件
- IConnection, IModel等的各种关闭事件
我对此有点困惑。它们是否意味着每次调用HandleBasicDeliver
时都会创建一个新线程?在这种情况下,接收到的消息将有尽可能多的线程,并发性由预取计数和消费者数量控制。
IConnection
和两个通道(IModel
),每个通道的预取计数为一个和一个 EventingBasicConsumer
,我们将在应用程序中运行多少线程?
自从我第一次问这个问题以来,我已经对这个话题做了相当多的研究,所以我想我应该把它贴在这里,以防有人发现这个信息有用。
-
对此持保留态度。以上是我对rabbit (c#)工作原理的理解。
-
IConnection是一个实际的套接字连接。它将有一个线程轮询它。根据我读到的建议,每个应用程序使用一个连接,除非你有理由使用更多。
- 使用多个连接并不一定意味着您有更好的容错能力,因为如果一个连接失败,通常会有一个问题,将导致所有连接失败。此外,在许多情况下,使用一个连接就足以处理来自网络的流量,根本没有必要拥有更多连接。http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2011-July/013771.htmlhttp://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2012-May/019873.html
-
在c#中通道不被认为是线程安全的,所以每个线程有一个通道不是一个坏主意,否则应该确保使用锁定机制。https://www.rabbitmq.com/dotnet-api-guide.html
-
根据我对阅读源代码的理解,handleBasicDeliver(我认为所有IModel调用)是在任务中运行的。考虑到这一点,拥有多个消费者确实会增加软件的并发性,因为如果一个消费者接收到消息并忙于处理它,另一个消费者可以自由地拾取消息并在不同的线程中执行它。此外,每个消费者必须在自己的通道上以最大化并发性,否则将保留消息顺序。但是,如果不欢迎这种并发性,请考虑使用单个通道来确保按照消息到达的顺序处理消息。注:第3点可能已经改变,通道顺序不再保留。我没有时间去探索新的变化,所以读完这篇文章,得出你自己的结论:https://github.com/rabbitmq/rabbitmq-dotnet-client/issues/251
-
我已经修改了我的答案,你做的研究看起来不错。
我使用Rabbitmq创建了一个应用程序,在这种情况下,我必须为IModel(通道)的数量共享相同的IConnection(连接)。这就是我们应该使用一个连接的方式,因为一个连接足以服务多个通道。
我曾经遇到的问题是,如果我为每个客户端创建一个连接,那么该队列的连接数量会继续增加,这将导致应用程序在一段时间后终止。
因此,除非必要,否则我们应该避免使用多个连接。如果可能的话,应该只对多个通道使用一个连接。IConnection, IModel:
各种关闭事件IModel即使down了IConnection仍然在那里。但是如果IConnection关闭了,那么那个连接下的所有IModel都会关闭。