我有一个使用Masstransit / RabbitMq在Web项目中使用的企业服务总线。我使用Masstransit的Request/Response模式执行RPC over MQ。
我在总线中创建多个ReceiveEndpoint来处理不同类型的消息。 ESB使用自定义配置文件来创建多个总线,因此我可以在某个单独的服务器上以逻辑方式实现Qos,甚至通过网络分发消费者,以便或多或少地提高性能。
最近我看到我的一个消费者受阻。如果我将一些消息发送给长时间运行的消费者(每个消息大约需要5秒钟),它看起来像是一个线程响应我的请求并同时发送消息等待以前的消息被消费。
到目前为止,我设置UseConcurrencyLimit(64)
没有改变任何内容,尝试将PrefetchCount
增加到50但是RabbitMq在队列详细信息中显示为0。
为什么消费者一次处理单个消息?
MassTransit v3.5.7
编辑:我后来找到了this thread。对我来说,这看起来像是一样的问题。
更新与Chris的示例有什么不同,我使用RabbitMq并使用反射创建消费者,这样我就可以使用配置文件管理ESB。仍然在RabbitMq manament控制台上看到Prefetch Count 0。
var busControl = Bus.Factory.CreateUsingRabbitMq(x =>
{
x.UseConcurrencyLimit(64);
IRabbitMqHost host = x.Host(new Uri(Config.host), h =>
{
h.Username("userName");
h.Password("password");
});
var obj = Activator.CreateInstance([SomeExistingType]);
x.ReceiveEndpoint(host, "queueName", e =>
{
e.PrefetchCount = 64;//config.prefetchCount;
e.PurgeOnStartup = true;
if (config.retryCount > 0)
{
e.UseRetry(retry => retry.Interval(config.retryCount, config.retryInterval));
}
e.SetQueueArgument("x-expires", config.timeout * 1000 /*Seconds to milliseconds*/);
e.SetQueueArgument("temporary", config.temporary);
e.Consumer(consumer, f => obj);
});
})
busControl.StartAsync();
UPDATE 2 虽然我将预取计数设置为1,让MassTransit处理工作负载,因为我有几个消费者服务器和一个RabbitMq集群。但是,当我向队列中发送许多消息时,所有线程都处于忙碌状态,发送方队列中等待的新请求将被一个空闲线程接收。我增加了预取计数,这样我最终会为新请求提供更多免费线程。我在配置接收端点时设置了预取计数,因为Chris建议我。谢谢。克里斯确认后,我会立即将克里斯的答复标记为答案。
答案 0 :(得分:1)
如果你在RabbitMQ控制台中看到0
预取计数,你可能会在错误的地方配置它。你应该有以下几点:
cfg.ReceiveEndpoint("my-queue", x =>
{
x.PrefetchCount = 64;
x.Consumer<MyConsumer>();
});
这会将接收端点使用者配置为64的预取计数,该计数应显示在RabbitMQ管理控制台上的使用者中。
另一方面,如果您的消费者使用Thread.Sleep()
之类的东西来阻止线程,我已经看到了可以限制线程池并发性的情况。