Limiting Azure Functions Rate of Service Bus Message Intake
Asked Answered
B

1

7

Suppose we have the following scenario:

  • Service Bus Queue with 10,000 messages
  • Azure Functions (on Consumption plan) with function set up as a trigger for the SB Queue
  • An external (out of our control) system which fails past a certain request rate

If I queue those 10k messages as fast as I can, the external system is not able to handle the concurrent load. I don't know how many function instances or app service instances ("scale out") Azure runs at the same time to process these messages.

Here is a code sample of what my function definition looks like:

public class MyQueueProcessor
{
    private IMyDependency MyDependency { get; }

    public MyQueueProcessor(IMyDependency myDependency)
    {
        MyDependency = myDependency;
    }

    [FunctionName(nameof(MyQueueProcessor))]
    public async Task Run([ServiceBusTrigger("my-queue-name", Connection = "MyQueueConnection")] string item, ILogger log)
    {
        var req = JsonConvert.DeserializeObject<MyQueueRequest>(item);

        log.LogInformation($"Beginning processing of " + req);

        // Valudate req
        // Call external service REST API
        await MyDependency.CallService(req, new { otherParameters = true });

        log.LogInformation($"Finished processing of " + req);
    }
}

I am not able to process all 10k messages with a single function because the external service call takes a number of seconds to complete (5-10s), and processing all of these messages with one function call would exceed the 10min maximum for function calls.

How can I limit the number of concurrent functions running that are consuming the messages from my queue?

Beatrizbeattie answered 15/4, 2020 at 14:52 Comment(3)
Maybe durable functions is what you need: learn.microsoft.com/en-us/azure/azure-functions/durable/…Giarla
I can see some setting for v1 host.json to control concurrent request learn.microsoft.com/en-us/azure/azure-functions/… (don't see for v2)Emptyheaded
This question and the answer bellow, reveals just some of the operational problems , and cognitive overhead, imposed by Azure Functions.Obsecrate
C
8

You can now limit the number of instances with "Enforce Scale Out Limit" in the Azure Portal under the "Scale out" menu on your Azure Function App. When it is turned off the limit will default to 200 instances on a consumption plan.

Note that when you are using the Service Bus binding each instance can also receive and process messages concurrently. You can limit this by setting maxConcurrentCalls in host.json. The default value is 16.

{
  "version": "2.0",
  "extensions": {
    "serviceBus": {
      "messageHandlerOptions": {
        "autoComplete": true,
        "maxAutoRenewDuration": "00:05:00",
        "maxConcurrentCalls": 16
      }
    }
  }
}

The maximum number of messages being processed concurrently will then be the number of instances multiplied by maxConcurrentCalls.

Czarevitch answered 10/2, 2021 at 16:20 Comment(1)
Keep in mind that this will affect all ServiceBusTriggered functions in the app. If you are trying to limit concurrency / throttle a specific function and not others, this will not be a valid solution.Opt

© 2022 - 2024 — McMap. All rights reserved.