简体   繁体   English

Azure ServiceBus OnMessage是否阻止呼叫?

[英]Azure ServiceBus OnMessage Blocking Call or Not?

We are utilizing Azure ServiceBus queues to process high volumes of client requests. 我们正在利用Azure ServiceBus队列来处理大量客户端请求。 However, the OnMessage call seems to be a blocking call, however the blocking on this call is incredibly inconsistent if it is indeed a blocking call. 但是, OnMessage调用似乎是一个阻塞调用,但如果它确实是一个阻塞调用,那么这个调用的阻塞是非常不一致的。

What I am attempting to accomplish is watch a queue on a permanent basis from a web service application (to allow metrics to be mined from the running application) 我试图完成的是从Web服务应用程序永久地查看队列(允许从正在运行的应用程序中挖掘指标)

I am creating the subscription below: 我正在创建以下订阅:

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

If I only have the subscription called once, the application stops watching the queue and thus stops processing the messages. 如果我只调用一次订阅,则应用程序停止观察队列,从而停止处理消息。 However, if I place a while loop around my subscribe call. 但是,如果我在我的订阅呼叫周围放置一个while循环。 So with great hesitation I wrote the below snippet to resubscribe if this OnMessage completed. 因此,如果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);
        }
    }
}

This fixed the problem of messages expiring to the dead letter due to not being picked up, however this caused other problems. 这解决了由于未被拾取而导致死信过期的问题,但这导致了其他问题。

With OnMessage being a billable operation I am concerned when I see the log file telling me that a queue is beginning and ending less than a second apart and the size of my log file increases very rapidly. 由于OnMessage是一个可计费操作,当我看到日志文件告诉我队列开始和结束不到一秒钟并且我的日志文件的大小增加得非常快时,我很担心。

I have my MessagingFactory set to have an OperationTimeout of 1 day, yet this does not seem to impact the frequency of the subscriptions open / close status as I would expect. 我将MessagingFactory设置为具有1天的OperationTimeout ,但这似乎不会像我期望的那样影响订阅打开/关闭状态的频率。

I have seen plenty of samples doing this as a worker role, however this will not accomplish what we are trying to do. 我已经看到很多样本作为工作者角色,但是这不会实现我们想要做的事情。 I am currently wiring this from the Global.asax.cs of our web application. 我目前正在从我们的Web应用程序的Global.asax.cs接线。 Any advice is greatly appreciated! 任何意见是极大的赞赏!

OnMessage and OnMessageAsync are NOT blocking calls. OnMessage和OnMessageAsync不会阻止调用。 These need instantiated a single time and will continue subscribing to the queue until the application is terminated. 这些需要实例化一次,并将继续订阅队列,直到应用程序终止。

See related post for further details: Azure Service Bus, determine if OnMessage stops processing 有关更多详细信息,请参阅相关帖子: Azure Service Bus,确定OnMessage是否停止处理

Your first approach is correct, and the value of MaxThreadsPerQueue determines how many threads are available to handle your messages. 您的第一种方法是正确的, MaxThreadsPerQueue的值确定可用于处理邮件的线程数。 It sounds as if these threads are being used up (maybe the processing of your messages by the callback is taking some time?). 听起来好像这些线程正在用完(可能回调处理你的消息需要一些时间?)。

You should instead consider using the QueueClient.OnMessageAsync Method to receive your messages. 您应该考虑使用QueueClient.OnMessageAsync方法来接收消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM