【问题标题】:Azure Function - Slow to aquire singleton lock and why is it needed?Azure 函数 - 获取单例锁的速度很慢,为什么需要它?
【发布时间】:2021-04-13 18:08:21
【问题描述】:

我有一个用 C#/netcoreapp3.1 编写的函数应用程序,它托管在消费计划上。它拥有 6 个定时器功能和 3 个队列功能。队列功能的执行速度比我想要的要慢。我希望这些函数平均在 200-300 毫秒内执行。我确实看到了这一点,但仅在每 10 条左右消息中。其余的需要更长的时间。这是其中一个队列函数的调用跟踪:

Timestamp Message Type
2021-01-07 21:08:22.255 Executing 'PriceHandler' (Reason='New queue message detected on 'price'.', Id=FOO) Information
2021-01-07 21:08:22.255 Executing '"PriceHandler"' (Reason='"New queue message detected on 'price'."', Id=FOO)
2021-01-07 21:08:22.256 Trigger Details: MessageId: BAR, DequeueCount: 3, InsertionTime: 2021-01-07T20:47:45.000+00:00 Information
2021-01-07 21:08:22.256 Trigger Details: MessageId: "BAR", DequeueCount: "3", InsertionTime: "2021-01-07T20:47:45.000+00:00"
2021-01-07 21:08:42.293 Singleton lock acquired (yadda)
2021-01-07 21:08:42.294 Processing Message : "{ Json msg ~2k bytes }" Information
2021-01-07 21:08:42.298 Start processing HTTP request "GET" https://api/123 Information
2021-01-07 21:08:42.298 Sending HTTP request "GET" https://api/123 Information
2021-01-07 21:08:42.379 Received HTTP response after 80.397ms - OK Information
2021-01-07 21:08:42.379 End processing HTTP request after 81.4436ms - OK Information
2021-01-07 21:08:42.491 Singleton lock released (yadda)
2021-01-07 21:08:42.492 Executed 'PriceHandler' (Succeeded, Id=FOO, Duration=20301ms) Information
2021-01-07 21:08:42.492 Executed '"PriceHandler"' ("Succeeded", Id=FOO, Duration=20301ms)

我注意到,对于大多数调用,“触发器详细信息”事件和“获得单例锁”之间存在很大延迟。几十秒如上图。我不确定为什么该函数需要“单例锁”,但有什么想法为什么函数运行时需要这么长时间才能得到它?另外,我将如何禁用它?如果可能的话,我希望该函数的多个实例在同一个 VM 上运行,并且我假设通过“单例锁”它不会这样做。

host.json:

{
  "version": "2.0",
  "functionTimeout": "00:10:00",
  "aggregator": {
    "batchSize": 1000,
    "flushTimeout": "00:00:30"
  },
  "extensions": {
    "queues": {
      "maxPollingInterval": "00:00:02",
      "visibilityTimeout": "00:05:00",
      "batchSize": 15,
      "maxDequeueCount": 600,
      "newBatchThreshold": 10
    }
  },
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "maxTelemetryItemsPerSecond": 20,
        "excludedTypes": "Request;Trace"
      }
    }
  },
  "Serilog": {
    "MinimumLevel": "Debug",
    "Override": {
      "Microsoft": "Information",
      "System": "Information"
    },
    "Enrich": [ "FromLogContext" ]
  },
  "WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT": 2
}

应用设置:
FUNCTIONS_EXTENSION_VERSION:~3
FUNCTIONS_WORKER_RUNTIME:点网
(...以及其他特定于应用程序的内容。)

任何帮助将不胜感激!

【问题讨论】:

    标签: azure-functions azure-web-app-service


    【解决方案1】:

    “获得单例锁”是函数reliable event processing 的策略。这里有一个队列触发功能的描述,可能有助于你理解。

    有了队列,可靠的消息传递自然而然。当与 函数触发,该函数在队列消息上创建一个锁。 如果处理失败,则释放锁以允许另一个实例 重试处理。然后继续处理,直到消息 评估成功,或者被添加到毒队列中。

    【讨论】:

    • 根据您收到的消息数量以及处理它们的速度,您可以尝试将横向扩展限制为仅 1 个 WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT=1 medium.com/microsoftazure/… 的函数实例,这可能有助于锁定问题
    【解决方案2】:

    事实证明,获取单例锁是导致性能不佳的主要原因。解决方案非常简单:从函数入口点方法中删除 [Singleton] 属性。 (我什至没有意识到他们在那里。睡个好觉后你会注意到的东西真是太神奇了!)

    编辑:该属性是很久以前添加的,不再需要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-03
      • 1970-01-01
      • 2013-09-06
      • 1970-01-01
      • 1970-01-01
      • 2011-04-26
      • 1970-01-01
      • 2015-02-19
      相关资源
      最近更新 更多