Azure Service Bus,确定OnMessage是否停止处理

Vul*_*ary 5 c# azure azure-servicebus-queues

使用Azure ServiceBus和OnMessage调用我正在寻找一种方法来确定OnMessage事件泵是否停止从队列中读取.

我们与OnMessage的连接配置如下:

protected virtual void DoSubscription(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();
                Log.Warn("DoSubscription: Message Failed to Process Gracefully: {0}{1}", Environment.NewLine, JsonConvert.SerializeObject(request));
            }
        }
        catch (Exception ex)
        {
            Log.Error("DoSubscription: Message Failed to Process With Exception:", ex);
            message.Abandon();
        }
    });
    var options = new OnMessageOptions
    {
        MaxConcurrentCalls = _config.GetInt("MaxThreadsPerQueue"),
        AutoComplete = false,
        AutoRenewTimeout = new TimeSpan(0,0,1)
    };
    options.ExceptionReceived += OnMessageError;
    client.OnMessage(transformCallback, options);
}
Run Code Online (Sandbox Code Playgroud)

我们遇到的问题是在一段时间没有消息排队后,OnMessage事件泵无法获取排队的新消息,直到应用程序重新启动.

我意识到有很多方法可以使用Worker Roles来实现这一点,但是出于监控和管理的目的,我们决定在Web应用程序的应用程序启动中实现它.

Vul*_*ary 6

因此,在与Microsoft的Azure支持团队通话后,在OnMessage或OnMessageAsync错误时没有事件要捕获.由于这些不是阻塞调用,它启动事件泵并返回执行线程,这会产生一个挑战,以确定OnMessage*是否正在执行它的工作.

微软的建议如下:

  • 创建自己的QueueClientBase类实现,该类公开您可以处理的OnClose,On*方法.但是,在执行此操作时,您必须自己处理邮件信封.
  • 在单独的线程循环中使用OnReceive,您可以自己捕获错误并立即重试.

然而,我确实探索了一些针对OnMessage的防弹,并发现了一些缓解我恐惧的事情.

  • OnMessage具有令人难以置信的容错能力
    • 我通过无线关闭从我的笔记本电脑上拔下了以太网电缆,这打破了OnMessage与Service Bus队列的连接.等待10分钟后,我重新插入以太网电缆,OnMessage立即开始处理排队的元素.
  • On Message令人惊讶地相当稳定.它已经在global.asax.cs App Start中运行,缩短了几天,Factory IdleTimeout设置为24小时,而没有重新启动Web应用程序72小时.

总而言之,我现在将继续使用OnMessage/OnMessageAsync,并密切关注它.如果我发现改变了我对OnMessage的看法的问题,我会更新这个.

旁白 - 确保在Azure网站中使用OnMessage进行永久监听,并将"始终打开"配置选项设置为"打开".否则,除非Web请求进入,否则OnMessage将被处理,并且在HTTP请求重新唤醒Web应用程序之前将不再处理消息.

  • 经过一个多月的不间断处理,"OnMessage"一直没有问题.在这个交汇点,我会说使用OnMessage是可以接受的,但没有能力确定停止状态而没有太大的顾虑.为了安全起见,我们有一个冗余来检查队列中最老的元素,如果它的年龄超过配置的年龄,它将通知我们.在我们的案例中,调查结果加上通知观察就足以继续采用这种方法. (5认同)
  • 另一个跟进......现在已经超过一年了.OnMessage的解决方案仍然没有动摇或失败.我支持我最初的声明,OnMessage具有足够的弹性,可以保持不变的生产使用. (2认同)