Azure Function Durable Timer 在应用程序被触摸之前不会唤醒

Sco*_*y H 8 azure azure-functions azure-durable-functions

我有一个 Durable Orchestration,可根据请求扩展和缩减 Azure Cosmos DB 吞吐量。放大是通过 HTTP 触发的,缩小是稍后通过Durable Timer发生的,该定时器应该在当前或下一小时结束时唤醒 Azure 函数。这是 Orchestrator 功能:

public static class CosmosDbScalerOrchestrator
{
    [FunctionName(nameof(CosmosDbScalerOrchestrator))]
    public static async Task RunOrchestrator(
        [OrchestrationTrigger] IDurableOrchestrationContext context)
    {
        var cosmosDbScalerRequestString = context.GetInput<string>();

        var didScale = await context.CallActivityAsync<bool>(nameof(ScaleUpActivityTrigger), cosmosDbScalerRequestString);

        if (didScale)
        {
            var minutesUntilLastMinuteOfHour = 59 - context.CurrentUtcDateTime.Minute;
            var minutesUntilScaleDown = minutesUntilLastMinuteOfHour < 15
                ? minutesUntilLastMinuteOfHour + 60
                : minutesUntilLastMinuteOfHour;
            var timeUntilScaleDown = context.CurrentUtcDateTime.Add(TimeSpan.FromMinutes(minutesUntilScaleDown));
            await context.CreateTimer(timeUntilScaleDown, CancellationToken.None);
            await context.CallActivityAsync(nameof(ScaleDownActivityTrigger), cosmosDbScalerRequestString);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是ScaleUpActivityTrigger

public class ScaleUpActivityTrigger
{
    [FunctionName(nameof(ScaleUpActivityTrigger))]
    public static async Task<bool> Run([ActivityTrigger] string cosmosDbScalerRequestString, ILogger log)
    {
        var cosmosDbScalerRequest =
            StorageFramework.Storage.Deserialize<CosmosDbScalerRequest>(cosmosDbScalerRequestString);

        var scaler = new ContainerScaler(cosmosDbScalerRequest.ContainerId);
        var currentThroughputForContainer = await scaler.GetThroughputForContainer();

        // Return if would scale down
        if (currentThroughputForContainer > cosmosDbScalerRequest.RequestedThroughput) return false;

        var newThroughput = cosmosDbScalerRequest.RequestedThroughput < 25000
            ? cosmosDbScalerRequest.RequestedThroughput
            : 25000;
        await scaler.Scale(newThroughput);

        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

ScaleDownActivityTrigger

public class ScaleDownActivityTrigger
{
    [FunctionName(nameof(ScaleDownActivityTrigger))]
    public static async Task Run([ActivityTrigger] string cosmosDbScalerRequestString, ILogger log)
    {
        var cosmosDbScalerRequest =
            StorageFramework.Storage.Deserialize<CosmosDbScalerRequest>(cosmosDbScalerRequestString);
        var scaler = new ContainerScaler(cosmosDbScalerRequest.ContainerId);
        var minimumRusForContainer = await scaler.GetMinimumRusForContainer();
        await scaler.Scale(minimumRusForContainer);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我观察到的是,在其他东西触发 Durable Orchestration 之前,函数不会被唤醒。请注意计划时间和发生时间的时间戳差异。

显示不同时间戳的 Azure 门户屏幕截图

直到那时它才被设计或错误唤醒的事实?如果是设计使然,我如何在真正想要的时候唤醒它?