【问题标题】:RabbitMQ best practice for creating many consumers创建多个消费者的 RabbitMQ 最佳实践
【发布时间】:2014-02-07 15:31:10
【问题描述】:

我们刚刚开始在 C# 中使用 RabbitMQ。我目前的计划是在数据库中配置在给定服务器上运行的消费者的数量和种类。我们有一个现有的 Windows 服务,当它启动时,我想产生所有的 RabbitMQ 消费者。我的问题是从 Windows 服务中生成这些的最佳方法是什么?

我目前的计划是从数据库中读取配置并为每个消费者生成一个长时间运行的任务。

                var t = new Task(() =>
                {
                    var instance = LoadConsumerClass(consumerEnum, consumerName);
                    instance.StartConsuming();//blocking call
                }, TaskCreationOptions.LongRunning);
                t.Start();

这比为每个消费者创建一个线程好还是坏?

                var messageConsumer = LoadConsumerClass(consumerEnum, consumerName);
                var thread = new Thread(messageConsumer.StartConsuming);

我希望有更多的人已经尝试过我正在做的事情,并且可以为我提供一些想法,告诉我哪些行得通,哪些行得通。

【问题讨论】:

    标签: c# windows-services rabbitmq


    【解决方案1】:

    EasyNetQ 中,我们为单个连接上的所有消费者提供了一个调度程序线程。我们还提供了从消息处理程序返回任务的工具,因此如果您想进行数据库调用、转到文件系统或发出 Web 服务请求,则可以轻松执行异步 IO。

    话虽如此,让每个消费者在不同的线程上消费是完全合法的。我想这取决于您的消息吞吐量、您拥有多少消费者以及您的消息处理程序的性质。

    【讨论】:

      【解决方案2】:

      我会坚持使用 Tasks,因为它们可以为您提供更多功能,并且通常允许使用更少的样板代码。 而且,如果我正确理解您的代码,您将在第二种情况下共享一个频道(IModel)。这可能会导致麻烦,因为默认的 IModel 实现不是线程安全的(或过去是)。您必须注意有关线程安全的更多细微差别。 但这取决于您的使用模式。如果您不希望每个消费者每秒有很多消息,或者如果您的应用可以快速处理消息,那么可能所有消费者的单个线程将是您的最佳选择。

      【讨论】:

      • 感谢 Kostassoid 的评论。我们将共享一个 IConnection,但每个消费者都会生成自己的 IModel,所以我们应该在那里做得很好。
      【解决方案3】:

      任务很棒,但你并不会真正使用它所能做的所有事情。您唯一需要做的就是并行工作。 几个月前我遇到了同样的问题,我完成的是每个计算类型(每个队列)的线程,它在消息到达时阻塞并且在等待消息时不消耗 cpu。 为每个线程打开一个新通道。 至于连接 - 如果您的应用程序旨在处理高负载的消息,我建议您为每个 X 工作人员打开连接(图你的 X),因为只有一个通道可以通过连接发送消息,所以假设一个工作人员是消耗大消息,其他人在连接级别被阻止,等待它空闲。

      【讨论】:

        猜你喜欢
        • 2020-11-24
        • 1970-01-01
        • 1970-01-01
        • 2014-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多