kos*_*kov 5 azure azureservicebus azure-servicebus-topics azure-functions
我的 host.json 中有这些,但每次我运行该函数时,它都会并行运行比 1 更多的线程(队列中有消息)
{
"version": "2.0",
"extensions": {
"serviceBus": {
"prefetchCount": 1,
"messageHandlerOptions": {
"maxConcurrentCalls": 1
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的职能
[FunctionName(nameof(ResourceEventProcessorFunction))]
public async Task Run([ServiceBusTrigger("%TopicName%", "%SubscriptionName%", Connection = "ServiceBusConnection", IsSessionsEnabled = true)]Message message, IMessageSession messageSession, ILogger log)
Run Code Online (Sandbox Code Playgroud)
由于您使用的是会话,因此您可以对所有消息使用相同的 sessionId,并且无论您的 host.json 中的设置如何,它们都将由单个实例按顺序处理。
https://learn.microsoft.com/en-us/azure/service-bus-messaging/message-sessions
Singleton属性如果您无法使用 sessionId 来达到您的目的,您应该尝试[Singleton]在您的函数中使用该属性。这将确保所有函数实例中只有一个实例将处理该请求。
我们已经在生产环境中的 WebJobs 中成功实现了此功能,并且它对于 Azure Functions 也应该同样有效。如果您有专用的应用程序服务计划,则使用此属性应该足够了。不建议将其用于消费计划。
[Singleton]确实适用于函数。Azure Function 主机将在 Azure 存储帐户中创建或等待锁定。锁是主机 ID,对于所有实例中应用程序的所有主机而言,该 ID 应该相同 - 因此所有实例共享此锁,并且一次只允许执行一次。为了测试这一点,我使用 [Singleton] 在函数上一次放置 1000 条队列消息。该函数将唤醒、发出调用 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)
Run Code Online (Sandbox Code Playgroud)
继续上面的引用:
话虽如此,我认为建议是:不建议将 [Singleton] 用于消费托管功能计划。如果您有专用的应用程序服务计划,那就没问题(因为无论如何您都要为实例付费)。如果您想在消费计划中强制实施类似 [Singleton] 的行为,您可能最好:
- 设置
WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT为 1,这样您就不会扩展到多个实例- 将文件设置
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
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以问题是每条消息都有不同的 sessionId。在 azure 中禁用订阅上的 sessionId 解决了这个问题。
下面详细介绍了赏金:D azure 文档并没有确切说明如何限制线程数量,但我看起来有点像。
存在MessageRecievePump
并且
SessionRecievePump
一个使用MaxConcurrentCalls另一个MaxConcurrentSessions并且MaxConcurrentAcceptSessionCalls
如果您在订阅中包含会话(MaxConcurrentCalls 不起作用),请注意这一点,它仅在会话 ID 相同时才起作用。当会话不同时尝试使用 MaxConcurrentSessions 或 MaxConcurrentAcceptSessionCalls 但请注意没有关于此的文档....
| 归档时间: |
|
| 查看次数: |
7549 次 |
| 最近记录: |