![](/img/trans.png)
[英]How to terminate a Durable orchestration with custom status in Azure Durable Functions
[英]How to execute a lot of durable functions triggered by Azure Queue?
简而言之,我们的任务是处理大量输入消息。
为了解决这个问题,我们决定使用 Azure 队列存储和 Azure Functions。 我们有类似于以下代码的 Azure Functions 结构:
队列触发功能
[FunctionName("MessageControllerExecutor")]
public static async void Run(
[QueueTrigger(QUEUE_NAME, Connection = QUEUE_CONNECTION_NAME)]string queueMessage,
[OrchestrationClient] DurableOrchestrationClient client,
TraceWriter log)
{
await client.StartNewAsync("MessageController", queueMessage);
}
耐用功能
[FunctionName("MessageController")]
public static async void Run(
[OrchestrationTrigger] DurableOrchestrationContext context,
TraceWriter log)
{
if (!context.IsReplaying) log.Warning("MessageController started");
var function1ResultTask = context.CallActivityAsync<ResultMessage>("Function_1", new InputMessage());
var function2ResultTask = context.CallActivityAsync<ResultMessage>("Function_2", new InputMessage());
await Task.WhenAll(function1ResultTask, function2ResultTask);
// process Function_1 and Function_2 results
// ...
}
简单活动函数示例
[FunctionName("Function_1")]
public static ResultMessage Run(
[ActivityTrigger] DurableActivityContext activityContext,
TraceWriter log)
{
var msg = activityContext.GetInput<InputMessage>();
int time = new Random().Next(1, 3);
Thread.Sleep(time * 1000);
return new ResultMessage()
{
Payload = $"Function_1 slept for {time} sec"
};
}
MessageControllerExecutor
在队列中接收到新项目时触发。 MessageController
是一个 Durable Function,它使用一些简单的活动函数来处理每条消息。
当我们将消息推送到队列时, MessageControllerExecutor
函数会立即启动并异步触发MessageController
并传递消息,因此这按预期工作。
但是我们面临着这个问题。 并非所有MessageController
函数实例都运行。
例如,我们将 100 条消息推送到队列中,但只有大约 10-20% 的消息被MessageController
处理。
某些消息未处理或处理延迟很长时间。 看起来持久函数未能启动 б,尽管没有抛出异常。
我们有几个问题:
为了我理解的简洁起见,您确实从上面的问题中的编排触发器中删除了一些代码,但是在await Task.WhenAll(...)
之后您到底在做什么? 如果它包含任何类型的重要处理,您应该真正将其分配给第三个操作函数(例如Function_3
)来执行,然后简单地从编排函数返回结果。
更新:我刚刚注意到你的函数被定义为async void
。 如果我不得不猜测,这实际上会导致运行时出现问题。 您可以尝试将其更改为async Task
并查看您的问题是否消失吗? 作为一般规则,在 .NET 中async void
将方法定义为async void
。
德鲁答案的一些扩展。 正如文档所述,您不应使用 Thread.Sleep(),而应使用 CreateTimer Api。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.