【问题标题】:Azure ServiceBus: Can not receive messages from queueAzure ServiceBus:无法接收来自队列的消息
【发布时间】:2017-01-01 17:36:24
【问题描述】:

我正在使用此代码从队列接收消息:

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
    }
}

问题是我只能在第一次运行 handleMessage() 时收到一条消息。进一步的 startReceiver() 可以获得正确的活动消息计数,但 handleMessage() 总是得到未定义的 msg 作为参数(即 serviceBusService.receiveQueueMessage() 失败,err 是“没有消息接收”)。

使用带有标准函数的 C# 库来接收消息效果很好。

这里有什么问题?请帮忙

编辑:我只是从 azure-sdk-for-node 存储库复制粘贴 this example,在我的情况下,它会产生相同的行为:已成功接收到第一条消息,但是遵循对 Bus 的请求返回“没有要接收的消息”

【问题讨论】:

  • 嗨@Mergasov,还有更新吗?
  • @Gary Liu - MSFT,我在这里忘记了答案,抱歉。问题是我有一个过时的 node js 包。当我更新它时,我的代码是有效的。

标签: javascript azure azureservicebus


【解决方案1】:

目前,我可以产生您的问题,并检测到它应该是某种复杂场景中的性能问题,它与从队列接收消息的Peek-Lock 模式有关。

在您的代码 sn-p 中,您使用 Peek-Lock 模式接收消息,这将锁定队列的第一条消息(因为队列传递消息 FIFO),因为您的 handleMessage() 函数中的 deleteMessage() 是一个异步函数,因此 node.js 不会等待这个结果,将立即在finally 部分调用startReceiver()。在这种情况下,它可能会尝试接收锁定的消息并出现此问题。

您可以尝试两种操作来解决此问题:

  • 放大接收处理器的间隔时间,尝试将finally部分下的startReceiver()修改为setTimeout(startReceiver, 3000);
  • 尝试使用read and delete接收模式,使用receiveQueueMessage(quene_name,callback)而不是receiveQueueMessage(quene_name,{ isPeekLock: true },callback)

【讨论】:

    【解决方案2】:

    我终于找到了解决这个问题的方法。

    起初我认为原因是 Node.js 的 Azure 包过时了。 然而事实并非如此。

    当我手动创建队列时,即通过 azure 门户,我的 node.js 客户端工作错误(它无法接收消息)。 并且用代码(createQueueIfNotExists 方法)创建时没有任何问题。

    这对我有用,但我对这种行为的细节一无所知,我向他们询问了团队。

    【讨论】:

    • 由于 CORS,您如何以编程方式创建队列?
    【解决方案3】:

    这是因为默认情况下,从 Azure 门户创建新队列时会选中分区复选框。在创建队列之前取消选中分区复选框。

    由于某种原因,节点客户端在从队列中读取消息时似乎从随机分区中抓取。您将从空的分区返回“没有消息接收”错误。我找不到任何说明如何将节点 sdk 与分区队列一起使用的文档。

    编辑:

    这里是一些解释分区的文档: https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-partitioning

    经过一番挖掘,我发现其余客户端(节点客户端使用的)不支持会话,或者换句话说,在从队列中读取消息时,您无法告诉客户端使用哪个分区。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-30
      • 1970-01-01
      • 2011-10-09
      相关资源
      最近更新 更多