Azure ServiceBus OnMessage是否阻止呼叫?

时间:2015-07-08 23:21:30

标签: c# azure-web-sites azure-servicebus-queues

我们正在利用Azure ServiceBus队列来处理大量客户端请求。但是,OnMessage调用似乎是一个阻塞调用,但如果确实是阻塞调用,则此调用的阻塞非常不一致。

我想要完成的是从Web服务应用程序永久地查看队列(允许从正在运行的应用程序中挖掘指标)

我正在创建以下订阅:

protected virtual void Subscribe(string queueName, Func<QueueRequest, bool> callback)
{
    var client = GetClient(queueName, PollingTimeout);
    var transformCallback = new Action<BrokeredMessage>((message) =>
    {
        try
        {
            var request = message.ToQueueRequest();
            if (callback(request))
            {
                message.Complete();
            }
            else
            {
                message.Abandon();
            }
        }
        catch (Exception ex)
        {
            //TODO: Log the error
            message.Abandon();
        }
    });
    var options = new OnMessageOptions
    {
        MaxConcurrentCalls = _config.GetInt("MaxThreadsPerQueue"),
        AutoComplete = false
    };
    options.ExceptionReceived += OnMessageError;
    client.OnMessage(transformCallback, options);
}

如果我只调用一次订阅,则应用程序停止观察队列,从而停止处理消息。但是,如果我在我的订阅呼叫周围放置一个while循环。因此,如果OnMessage已完成,我会非常犹豫地写下以下代码段重新订阅。

protected void MonitorQueue()
{
    IsRunning = true;
    while (IsRunning)
    {
        try
        {
            Log.Info("MonitoringThread: OnMessage beginning logging for {0}", QueueName);
            QueueClient.Subscribe(QueueName, Processor);
            Log.Info("MonitoringThread:  OnMessage ended logging for {0}", QueueName);
        }
        catch (Exception ex)
        {
            IsRunning = false;
            Log.Error("MonitoringThread: Error in subscription for {0}: ", ex, QueueName);
        }

        if (SleepBeforeReinit > 0 && IsRunning)
        {
            Thread.Sleep(SleepBeforeReinit);
        }
    }
}

这解决了由于没有被接收而导致死信到期的问题,但这导致了其他问题。

OnMessage是一个可计费操作,当我看到日志文件告诉我队列开始和结束不到一秒钟并且我的日志文件的大小快速增加非常时,我很担心。

我的MessagingFactory设置为{1}}为1天,但这似乎并没有像我预期的那样影响订阅打开/关闭状态的频率。

我已经看到很多样本作为工作者角色,但这不会实现我们想要做的事情。我目前正在从我们的Web应用程序的Global.asax.cs接线。非常感谢任何建议!

2 个答案:

答案 0 :(得分:1)

OnMessage和OnMessageAsync不阻止调用。这些需要实例化一次,并将继续订阅队列,直到应用程序终止。

有关详细信息,请参阅相关文章:Azure Service Bus, determine if OnMessage stops processing

答案 1 :(得分:0)

您的第一种方法是正确的, MaxThreadsPerQueue 的值决定了可用于处理邮件的线程数。听起来好像这些线程正在用完(可能回调处理你的消息需要一些时间?)。

您应该考虑使用QueueClient.OnMessageAsync Method来接收邮件。