【问题标题】:Azure Service Bus, determine if OnMessage stops processingAzure 服务总线,确定 OnMessage 是否停止处理
【发布时间】:2015-07-10 15:40:28
【问题描述】:

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

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

我知道使用 Worker Roles 可以做到这一点,但出于监控和管理目的,我们决定在 Web 应用的 Application Start 中实现这一点。

【问题讨论】:

  • 你检查死信队列了吗?如果那里有消息,您应该能够看到消息处理失败的原因。
  • 在 DL 中他们只是超时。以编程方式,该过程刚刚停止。

标签: c# azure azure-servicebus-queues


【解决方案1】:

因此,在与 Microsoft 的 Azure 支持团队通话后,不会在 OnMessage 或 OnMessageAsync 错误时捕获事件。由于这些不是阻塞调用,它会启动事件泵并返回到执行线程,这对确定 OnMessage* 是否正在执行它的工作提出了挑战。

来自微软的建议是:

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

但是,我确实探索了一些针对 OnMessage 的防弹措施,并发现了一些减轻我恐惧的事情。

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

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

除此之外 - 如果您在 Azure 网站中使用 OnMessage 进行永久侦听,请确保您将“始终开启”配置选项设置为“开启”。否则,除非 Web 请求进入,否则 OnMessage 将被释放并且消息将不再被处理,直到 Web 应用程序被 HTTP 请求重新唤醒。

【讨论】:

  • 经过一个多月的不间断处理,OnMessage 一直在正常工作。在这个交界处,我会说使用 OnMessage 而不需要确定停止状态的能力是可以接受的。为了安全起见,我们有一个冗余来检查队列中最旧的元素,如果它的年龄超过了配置的年龄,它会通知我们。在我们的案例中,调查结果加上注意通知就足以继续这种方法。
  • 又一次跟进……现在已经一年多了。 OnMessage 的解决方案仍然没有动摇或失败。我坚持我最初的说法,OnMessage 具有足够的弹性,可以在不改变的生产环境中使用。
  • 在什么过程中实例化 QueueClient ?以及如何防止垃圾收集?
  • 当您说您将工厂 IdleTimeout 设置为 24 小时时;你在哪里设置的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-18
  • 2017-03-28
  • 2020-07-20
  • 2017-11-01
  • 1970-01-01
相关资源
最近更新 更多