4
votes

I've seen this problem expressed a lot but I've yet to find a working solution.

In short, I periodically have a large batch of processing operations to be done. Each operation is handled by an Azure Function. Each operation makes calls to a database. If I have too many concurrent functions running at the same time, this overloads the database and I get timeout errors. So, I want to be able to limit the number of concurrent Azure Function calls that are run at a single time.

I've switched the function to be queue-triggered and tweaked the batchSize / newBatchThreshold / maxDequeueCount host.json settings in many ways based on what I've seen online. I've also set the WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT application setting to 1 in my function application settings to prevent more than one VM from being spawned.

Yet still, every time I fill that queue, multiple functions will spawn indiscriminately and my database will fall over.

How can I throttle the number of concurrent operations?

1
Based on the documentation there is no concurrent request handling for queue trigger. "WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT" this is in preview mode in V2 and currently there is no info on the field . HttpTrigger supports max concurrent request. github.com/Azure/Azure-Functions/issues/523Baskar Rao
@vargonian - what exactly are your configurations? Have you the combination of batchSize = 1 and WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT = 1?Marie Hoeger
@MarieHoeger Yes I've tried that combination, and it looks like maybe it's partially working insomuch as it's not scaling out (I'm guessing), but it still creates as many Azure Functions instances as one VM can handle because the trigger won't wait for a function instance to complete before pulling another item off the queue. So I can't gate it to just one at a time, for example. I'm hoping there's a way to do this.vargonian
To limit the outgoing connections from one FunctionApp instance you can use a SemaphoreSlim as a static member (docs.microsoft.com/de-de/dotnet/api/…)Sebastian Achatz
@vargonian - Hmm, ok either the host.json value is not getting honored or the app setting for scale-out is not getting honored. Each VM contains one instance of a function app, but function executions may occur concurrently if the host.json value is not being honored. Are you seeing concurrent function execution when running locally as well?Marie Hoeger

1 Answers

9
votes

The problem ended up being a difference in formatting of host.json in V1 and V2 Functions. Below is the correct configuration (using Microsoft.Azure.WebJobs.Extensions.Storage at least 3.0.1). The following host.json configures a single function app to process queue messages sequentially.

{ 
  "version":"2.0",
  "extensions": { 
    "queues": { 
      "batchSize": 1,
      "newBatchThreshold": 0 
     }
   } 
}

Setting App Setting WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT = 1 restricts a function app from dynamically scaling out beyond one instance.