目前正在处理一个项目,我正在使用存储队列来获取要处理的项目。存储队列触发函数从队列中提取项目并启动持久编排。通常,根据文档,存储队列会并行处理 16 条消息(默认情况下)进行处理(https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-queue),但是由于编排刚刚开始(简单快速的过程),以防万一我有很多队列中的消息最终会同时运行很多编排。我希望能够启动编排并等待它完成,然后再接收下一批消息进行处理,以避免我的系统过载。我想出并且似乎有效的解决方案是:
public class QueueTrigger
{
[FunctionName(nameof(QueueTrigger))]
public async Task Run([QueueTrigger("queue-processing-test", Connection = "AzureWebJobsStorage")]Activity activity, [DurableClient] IDurableOrchestrationClient starter,
ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {activity.ActivityId}");
string instanceId = await starter.StartNewAsync<Activity>(nameof(ActivityProcessingOrchestrator), activity);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
var status = await starter.GetStatusAsync(instanceId);
do
{
status = await starter.GetStatusAsync(instanceId);
} while (status.RuntimeStatus == OrchestrationRuntimeStatus.Running || status.RuntimeStatus == OrchestrationRuntimeStatus.Pending);
}
基本上是接收消息,开始编排,然后在 do/while 循环中等待状态为 Pending 或 Running。 我在这里遗漏了什么,或者有什么更好的方法可以做到这一点(我在网上找不到太多东西)。 预先感谢您的意见或建议!
答案 0 :(得分:0)
这可能不起作用,因为您可能会遇到超时导致重复的编排运行,或者只是强制您的函数应用向外扩展,从而破坏了代码的全部目的。
相反,您可以依赖 Durable Functions 附带的 concurrency throttles。虽然队列触发器会将业务流程运行排队,但只有定义的最大值才会在函数的单个实例上运行。
这仍会导致您的函数应用向外扩展,因此您在设置此限制时也必须考虑这一点,您还可以设置 WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT
应用设置来控制函数应用可以扩展的实例数量出去。