Search code examples
javascriptnode.jsazureazure-servicebus-queues

Azure Service Bus Queues slow to send message


So I'm trying to send a message to an Azure Service Bus Queue from node.js I'm using the boilerplate code as described in the Azure documentation.

var message = {
body: 'Test message',
customProperties: {
    testproperty: 'TestValue'
}};
serviceBusService.sendQueueMessage('myqueue', message, function(error){
if(!error){
    // message sent
}});

When I send a single message every few seconds it works fine and I'm able to see the message get picked up by my worker after a second or so, but once I start sending more messages (5-10 per second) it looks like it starts choking and I see a performance decrease to only sending out a message every 5 - 8 seconds. Is there Any way to increase the performance and keep the FIFO ordering? Could this be an issue of latency since I'm running my node code and my worker locally?

NOTE: I'm using basic non-partitioned queues.


Solution

  • To optimize sending performance of Service Bus, we can leverage client-side batching if your application support asynchronous Send and Complete operations. You can get details on official article https://azure.microsoft.com/en-us/documentation/articles/service-bus-performance-improvements/#client-side-batching.

    However, client using batch to send messages is only integrated in .Net SDK, in Node.js we should implement custom requests via REST API https://msdn.microsoft.com/en-us/library/azure/dn798894.aspx.

    To implement custom requests via REST API, we need to create the authentication credentials first on Azure portal:

    • Go to Azure Managment Portal, in the menu on the left select "SERVICE BUS".
    • Select the Namespace you created.
    • On the top menu select QUEUES.
    • Select the QUEUE to go to the details screen
    • Go to the CONFIGURE tab and go to the section "Shared access policies"
    • Create a new policy, enter a name and select the "Send" permission for sending messages
    • Save it by pressing the SAVE button at the bottom of the page
    • Go to the section "Shared access key generator"
    • Select your Policy and copy the PRIMARY KEY
    • Save this key, you will use it later

    Then you can leverage this code sample to generate the SAS Token for sending batch messages, https://github.com/dx-ted-emea/azure-tessel/blob/master/labs/service-bus-queues/CreateSASToken.js

    Here is the code snippet:

    var https = require('https');
    var crypto = require('crypto');
    // ServiceBus parameters
    var namespace = '<Your-ServiceBus-Namespace>';
    var queue ='<Your-Queue>';
    var AccessKeyName = '<Your-AccessKey-Name>';
    var AccessKey = '<Your-AccessKey>';
    // Full ServiceBus Queue publisher URI
    
    var ServiceBusUri = 'https://' + namespace + '.servicebus.windows.net' + '/' + queue;
    function createSASToken(uri, keyName, key) {
                    var expiry = parseInt(Date.now()/1000)+3600;
                    var signedString = encodeURIComponent(uri) + '\n' + expiry;
                    var hmac = crypto.createHmac('sha256', key);
                    hmac.update(signedString);
                    var signature = hmac.digest('base64');
                    var token = 'SharedAccessSignature sr=' + encodeURIComponent(uri) + '&sig=' + encodeURIComponent(signature) + '&se=' + expiry + '&skn=' + keyName;
    
                    return token;
    }
    
    var createdSASToken = createSASToken(ServiceBusUri, AccessKeyName, AccessKey);
    var options = {
                    hostname: namespace + '.' + 'servicebus.Windows.net',
                    port: 443,
                    path: '/' + queue + '/messages',
                    method: 'POST',
                    headers: {
                                    'Authorization': createdSASToken,
                                    'Content-Type': 'application/vnd.microsoft.servicebus.json',
                    }
    };
    var req = https.request(options, function(res) {
                    console.log("SendMessageInQueue:statusCode: ", res.statusCode);
                    res.setEncoding('utf8');
                    res.on('data', function(d) {
                    });
    });
    req.on('error', function(e) {
                    console.error(e);
    });
    var messages = [{
                    "Body": "This is the first message"
    }, {
                    "Body": "This is the second message"
    }, {
                    "Body": "This is the third message"
    }];
    req.write(JSON.stringify(messages));
    req.end();
    

    This solution is based on https://github.com/dx-ted-emea/azure-tessel/tree/master/labs/service-bus-queues.