问题
Using the Azure NodeJS libraries, I'm unable to receive messages off of an Azure Service Bus Queue any faster than 5 or 6 messages a second. This is orders of magnitude slower than what the official docs suggest. I'm using a Queue with partitioning turned off (as recommended here Polling an Azure Service Bus Queue from an Azure WebJob using Node.js), reading in ReceiveAndDelete mode. Essentially I am just calling .receiveQueueMessage() repeatedly.
Based on this question (Azure Service Bus Scalability) seems like others are also seeing 5/6 messages a second when using NodeJS. Is this pretty much a hard limit? Any known workarounds or optimizations?
回答1:
The code in the thread which you provide is awesome, and it seems to receive messages from Service Bus Queue in a pipeline workflow, which will receive the next message after finished receiving the previous one.
And as mentions on official site at High-throughput queue section under Scenarios stage, we can find the following points which are appropriate to your situation:
To increase the overall receive rate from the queue, use multiple message factories to create receivers.
Use asynchronous operations to take advantage of client-side batching.
Set the batching interval to 50ms to reduce the number of Service Bus client protocol transmissions. If multiple senders are used, increase the batching interval to 100ms.
To achieve these optimizations, we can leverage the sample on Azure github repo.
And to Maximize the throughput of a single queue. I have a simply test leveraging the sample code above and set the loop time to 10ms. The result in my test is: it will get nearly 50 messages per second in ReceiveAndDelete mode; and it will get about 70 messages per second in PeekLock mode, shown at 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);
}
});
来源:https://stackoverflow.com/questions/34111382/max-throughput-for-azure-service-bus-queue-with-node-js-library