使用Azure NodeJS库,我无法以每秒5或6条消息的速度从Azure Service Bus Queue接收消息。这比官方文档建议的要慢几个数量级。我正在使用关闭分区的队列(按照此处Polling an Azure Service Bus Queue from an Azure WebJob using Node.js的建议),在ReceiveAndDelete模式下读取。基本上我只是反复调用.receiveQueueMessage()。
基于这个问题(Azure Service Bus Scalability)似乎其他人在使用NodeJS时也会看到5/6个消息。这几乎是一个硬限制吗?任何已知的解决方法或优化?
答案 0 :(得分:3)
您提供的线程中的代码非常棒,它似乎从管道工作流中的Service Bus Queue接收消息,它将在收到上一个消息后收到下一条消息。
正如在场景阶段的高吞吐量队列部分official site中提及的那样,我们可以找到适合您情况的以下几点:
要提高队列的总体接收率,请使用多个 消息工厂创建接收器。
使用异步操作来利用客户端 配料。
将批处理间隔设置为50毫秒以减少服务总线的数量 客户协议传输。如果使用多个发件人,请增加 批处理间隔为100ms。
为了实现这些优化,我们可以利用sample on Azure github repo。
最大化单个队列的吞吐量。我有一个简单的测试,利用上面的示例代码,并将循环时间设置为10毫秒。 我测试的结果是:在ReceiveAndDelete模式下,它每秒将获得近50条消息;它将在PeekLock模式下每秒获得大约70条消息,显示在https://azure.microsoft.com/en-us/documentation/articles/service-bus-nodejs-how-to-use-queues/#receive-messages-from-a-queue
var uuid = require('node-uuid');
var azure = require('azure');
var serviceBus = azure.createServiceBusService(connectionString);
function checkForMessages(sbService, queueName, callback) {
sbService.receiveQueueMessage(queueName,{ isPeekLock: true }, function (err, lockedMessage) {
if (err) {
if (err === 'No messages to receive') {
console.log('No messages');
} else {
callback(err);
}
} else {
callback(null, lockedMessage);
}
});
}
function processMessage(sbService, err, lockedMsg) {
if (err) {
console.log('Error on Rx: ', err);
} else {
console.log('Rx: ', lockedMsg);
sbService.deleteMessage(lockedMsg, function(err2) {
if (err2) {
console.log('Failed to delete message: ', err2);
} else {
console.log('Deleted message.');
}
})
}
}
var idx = 0;
function sendMessages(serviceBus, queueName) {
var msg = 'Message # ' + (++idx) + (' '+uuid.v4());
serviceBus.sendQueueMessage(queueName, msg, function (err) {
if (err) {
console.log('Failed Tx: ', err);
} else {
console.log('Sent ' + msg);
}
});
}
var queueName = 'myqueue';
serviceBus.getQueue(queueName, function (err,res) {
if (err) {
console.log('Failed: ', err);
} else {
console.log('current msg count '+ res.MessageCount);
// var t = setInterval(checkForMessages.bind(null, serviceBus, queueName,function(err, lockedMsg){}), 10); //ReceiveAndDelete mode
var t = setInterval(checkForMessages.bind(null, serviceBus, queueName, processMessage.bind(null, serviceBus)), 10); // PeekLock mode
// setInterval(sendMessages.bind(null, serviceBus, queueName), 100);
setTimeout(function(){
clearInterval(t);
console.log('task over');
},1000);
}
});