Azure ServiceBus: Can not receive messages from queue

醉酒当歌 提交于 2019-12-11 07:27:57

问题


I'm working with this code for receiving messages from a queue:

function startReceiver(){
serviceBusService.getQueue(configurations.queueForRequest, function(err, queue){
    if(!err){
    var length = queue.CountDetails['d2p1:ActiveMessageCount'];//get count of active messages
    if(length > 0) {        
    serviceBusService.receiveQueueMessage(configurations.queueForRequest, {isPeekLock:true},
         function(error, lockedMessage){ HandleMessage(error, lockedMessage) });
    return; //get out from this method
               }
            }
            else{
                console.log('Can not get queue');
            }
        setTimeout(startReceiver, 3000);//if err or there are no messages then call this method later
        });    
    }

function handleMessage(err, msg){           
    var result;
    if (!err){
    serviceBusService.deleteMessage(msg, function(deleteError){
            if(deleteError) {
            console.log('Can not delete the message')
            }
            else{
            console.log('Msg has been deleted');
            }
          });//delete the message which has been received

    try{                
        result = GetResult(msg.body)        
    }
    catch (er){
        result = GetResultWhenExp();
    }
    finally{
        sendMessage(result); //send a response
        startReceiver(); //repeat a receiver loop
    }

    }//!error
    else{console.log('Error occured: '+err);
     setTimeout(startReceiver, 3000); //repeat a receiver loop later
    }
}

The issue is I can receive a message when handleMessage() is running the first time only. Further startReceiver() can get the correct count of active messages, but handleMessage() gets undefined msg as argument always (i.e. serviceBusService.receiveQueueMessage() fails, err is "No messages to receive").

Using C# library with its standard fucnctions for receiving messages it works great.

What's wrong here? Please help

Edit: I just copy-paste this example from azure-sdk-for-node repository and in my case it yields same behavior: first message has been received succesfully, however following requests to Bus returns "No messages to receive"


回答1:


Currently, I can produce your issue, and detect that it should be the performance issue in some kind of a complicated scenario which relates to the Peek-Lock mode to receive messages from queue.

As in your code snippet, you use Peek-Lock mode to receive messages, which will lock the first message of the queue (as queue delivers message FIFO), as the deleteMessage() in your handleMessage() function is an asyn function, so node.js will not pending on for this result, will call startReceiver() in finally section immediately. In which case it may try to receive a locked message and arise this issue.

There are two operations you can try to fix this issue:

  • Enlarge the receive processor's interval time, try to modify startReceiver() under finally section to setTimeout(startReceiver, 3000);
  • Try to use read and delete receive mode, use receiveQueueMessage(quene_name,callback) instead of receiveQueueMessage(quene_name,{ isPeekLock: true },callback)



回答2:


Finally I found how to resolve that issue.

At first I thought the cause is outdated Azure package for Node.js. However it's not true.

When I create a queue manually, i.e. through azure portal my node.js client works wrong (it can not receive messages). And when it is created with code (createQueueIfNotExists method) there are no any problems.

It's working for me but I don't know anything about details of this behavior and I asked about them the team.




回答3:


This is because, by default, the partitions checkbox is checked when creating a new queue from the azure portal. Uncheck the partitions checkbox before creating a queue.

For some reason the node client seems to grab from a random partition when reading messages from a queue. You will get back a "No messages to receive" error from a partition that is empty. I'm not able to find any documentation that explains how to use the node sdk with partitioned queues.

EDIT:

Here is some documentation explaining partitions: https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-partitioning

After some digging, I discovered that the rest client (what the node client uses) does not support sessions, or in other words, you cannot tell the client which partition to use when reading messages from a queue.



来源:https://stackoverflow.com/questions/41417504/azure-servicebus-can-not-receive-messages-from-queue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!