繁体   English   中英

azure servicebus maxConcurrentCalls 完全被忽略

[英]azure servicebus maxConcurrentCalls totally ignored

我的 host.json 中有这些,但是每次我运行该函数时,它都会并行运行比 1 多得多的线程(因为队列中有消息)

{
  "version": "2.0",
  "extensions": {
    "serviceBus": {
      "prefetchCount": 1,
      "messageHandlerOptions": {
        "maxConcurrentCalls": 1
      }
    }
  }
}

我的功能

 [FunctionName(nameof(ResourceEventProcessorFunction))]
    public async Task Run([ServiceBusTrigger("%TopicName%", "%SubscriptionName%", Connection = "ServiceBusConnection", IsSessionsEnabled = true)]Message message, IMessageSession messageSession, ILogger log)

利用会话

由于您使用的是会话,因此您可以对所有消息使用相同的 sessionId,并且无论您的 host.json 中的设置如何,它们都将由单个实例按顺序处理。

https://docs.microsoft.com/en-us/azure/service-bus-messaging/message-sessions

使用Singleton属性

如果您不能将 sessionId 用于您的目的,您应该尝试在您的函数上使用[Singleton]属性。 这将确保所有函数实例中只有一个实例会处理请求。

我们已经在生产中成功地为 WebJobs 工作,它对于 Azure Functions 的工作应该是一样的。 如果您有专门的应用服务计划,使用此属性应该就足够了。 不建议将其用于消费计划

[Singleton]确实适用于函数。 Azure Function 主机将在 Azure 存储帐户中创建或等待锁定。 锁是主机 ID,对于所有实例中的应用程序的所有主机都应该相同 - 因此所有实例共享此锁并且一次只允许执行一次。

为了测试这一点,我一次将 1000 条队列消息放在一个带有 [Singleton] 的函数上。 该函数将唤醒,发出调用 ID,休眠,然后发出调用 ID。 处理完所有 1000 个后,我查看了日志,但从未看到调用 ID 重叠。 一次只会在全局范围内发生一次调用。

https://github.com/Azure/azure-functions-host/issues/912#issuecomment-419608830

 [Singleton]
 [FunctionName(nameof(ResourceEventProcessorFunction))]
    public async Task Run([ServiceBusTrigger("%TopicName%", "%SubscriptionName%", Connection = "ServiceBusConnection", IsSessionsEnabled = true)]Message message, IMessageSession messageSession, ILogger log)

在消费计划中

继续上面的引用:

话虽如此,我认为建议是:[Singleton] 不推荐用于消费托管功能计划。 如果您有专门的应用程序服务计划,那很好(因为您无论如何都要为实例付费)。 如果您想在消费计划中强制执行类似 [Singleton] 的行为,您可能最好:

  1. WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT设置为 1,这样您永远不会扩展到多个实例
  2. host.json文件设置为该host.json仅允许 1 个并发执行(例如,Azure 队列的批处理大小为 1)。

https://github.com/Azure/azure-functions-host/issues/912#issuecomment-419608830

{
  "version": "2.0",
  "extensions": {
    "serviceBus": {
      "prefetchCount": 1,
      "messageHandlerOptions": {
        "maxConcurrentCalls": 1
      }
    }
  }
}

也许您可以将WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT设置为 1,以使该函数一次仅运行一个实例。

如果在本地开发,可以在local.settings.json设置,如果在Azure portal开发,可以在Configuration -> Application settings

笔记:

1.如果您将WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT设置为 1,您的函数将不会向外扩展,并且只能在一个实例中运行。

2.除了设置WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT ,还需要设置maxConcurrentCalls为 1

3.此设置处于预览状态。 已添加功能最大扩展的应用程序属性,并且是限制扩展的推荐方法。

更详细的可以参考这个官方文档

所以问题是每条消息都有一个不同的 sessionId。 在 azure 中禁用订阅的 sessionId 解决了这个问题。

在下面的赏金细节中:D azure docs 没有确切说明如何限制线程数,但我看起来有点北斗七星。

MessageRecievePumpSessionRecievePump一个使用MaxConcurrentCalls另一个MaxConcurrentSessionsMaxConcurrentAcceptSessionCalls

如果您在订阅中包含会话(MaxConcurrentCalls 不起作用),请注意这一点,它仅在会话 ID 相同时才起作用。 当会话不同时尝试使用 MaxConcurrentSessions 或 MaxConcurrentAcceptSessionCalls 但请注意没有关于此的文档....

暂无
暂无

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

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