问题
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()
underfinally
section tosetTimeout(startReceiver, 3000);
- Try to use
read and delete
receive mode, usereceiveQueueMessage(quene_name,callback)
instead ofreceiveQueueMessage(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