【发布时间】:2019-07-02 10:55:47
【问题描述】:
它在 RabbitMQ 文档中声明如下
“根据经验,在线程之间共享 Channel 实例是 要避免的事情。应用程序应该更喜欢使用通道 每个线程而不是跨多个共享相同的通道 线程。”
目前我们正在查看预取计数,建议如果您有少量消费者并且 autoack=false,那么我们应该一次消费许多消息。但是,我们发现如果消费者使用单个执行线程发回手动确认,则预取无效。但是,如果我们将消费者处理包装在一个任务中,我们会发现预取计数确实很重要,并且大大提高了消费者的性能。
请参阅以下示例,其中我们将消费者对消息的消费包装在 Task 对象中:
class Program
{
public static void Main()
{
var factory = new ConnectionFactory()
{
HostName = "172.20.20.13",
UserName = "billy",
Password = "guest",
Port = 5671,
VirtualHost = "/",
Ssl = new SslOption
{
Enabled = true,
ServerName = "rabbit.blah.com",
Version = System.Security.Authentication.SslProtocols.Tls12
}
};
var connection = factory.CreateConnection();
var channel = connection.CreateModel();
channel.BasicQos(0, 100, false);
channel.ExchangeDeclare(exchange: "logs", type: "fanout");
var queueName = channel.QueueDeclare().QueueName;
Console.WriteLine(" [*] Waiting for logs.");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var _result = new Task(() => {
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
System.Threading.Thread.Sleep(80);
channel.BasicAck(ea.DeliveryTag, false);
});
_result.Start();
};
channel.BasicConsume(queue: "test.queue.1", autoAck: false, consumer: consumer);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}
}
我的问题是人们如何使用 .NET rabbitmq 客户端实现消费者,利用预取计数?,你必须使用某种任务手动确认吗?,它安全吗
【问题讨论】:
-
就我个人而言,我讨厌 RabbitMQ API,在此过程中您会发现更多的错误(例如,即使您在选项中说您需要一条一条地使用消息,它仍然会消耗多条消息!该死!) .最好使用一些消息总线 API,如 MassTransit。它隐藏了可能导致死锁的有趣的通道操作、队列管理和连接损坏。它还支持模拟 rabbitmq 进行测试。
-
@eocron - RabbitMQ .NET 客户端是open source,我们(RabbitMQ 团队)定期收到拉取请求以修复错误和改进代码。与其声称堆栈溢出,不如为项目贡献您的专业知识?
-
@LukeBakken 是通过使用任务发回确认来利用预取计数性能优势的唯一方法吗?