3
votes

I have an Azure Function triggered by Azure Service Bus queue - Azure Function App is hosted in consumption plan.

How long does it take at most to wake up an Azure Function when new message in queue appears? (assuming there were no message during past 20 minutes).

Is it specified anywhere? I've found in the Documentation that:

For non-HTTP triggers, new instances will only be allocated at most once every 30 seconds.

Does it mean that I won't be able to process the first message in the queue faster than within 30 seconds?

Will adding Timer Triggered Azure Function to the same Function App (along with Service Bus triggered) help to keep the Azure Function instance up and running ?

3

3 Answers

2
votes

First of all, when using consumption plan and idle for about 20 minutes, the function app goes into idle. And then if you use the function, you will experience cold start, which needs to take some time to wake up.

For your question:

Does it mean that I won't be able to process the first message in the queue faster than within 30 seconds?

It depends on following(link is here):

1.which language you're using(eg. function using c# is more faster than java), the following is picked up from the link above:

A typical cold start latency spans from 2 to 15 seconds. C# functions usually complete the start within 3 seconds, while JavaScript and Java have longer tails.

2.The number of dependencies in your function:

Adding dependencies and thus increasing the deployed package size will further increase the cold start durations.

will adding Timer Triggered Azure Function to the same Function App (along with Service Bus triggered) help to keep the Azure Function instance up and running ?

Yes, add a Timer Triggered azure function to the same function app would keep the others warm up(up and running).

2
votes

Another option to handle a "cold start" of the ServiceBusTrigger function is using an eventing feature of the Azure Event Grid, where the events are emitted immediately if there are no messages in the Service Bus entity and a new message arrives. See more details here.

Note, that the event is emitted immediately when the first message arrived into the service bus entity. In the case, when the messages are there, the next event is emitted based on the idle time of the listener/receiver. This idle (watchdog) time is periodically 120 seconds from the last time used the listener/receiver on the service bus entity.

This is a push model, no listener on the service bus entity, so the AEG Subscriber (EventGridTrigger function) will "balanced" receiving a message with the ServiceBusTrigger function (its listener/receiver).

Using the REST API for deleting/receiving a message from the service bus entity (queue), the subscriber can obtained it very easy and straightforward.

So, using the AEG eventing on the topic providers/Microsoft.ServiceBus/namespaces/myNamespace and filtering on the eventType = "Microsoft.ServiceBus.ActiveMessagesAvailableWithNoListeners", the messages can be received side by side with a ServiceBudTrigger function and to solve the AF problem on the "cold start".

Note, that only the Azure Service Bus premium tier is integrated to AEG.

The following code snippet shows an example of the AEG Subscriber for Service Bus using the EventGridTrigger function:

#r "Newtonsoft.Json"

using System;
using System.Threading.Tasks;
using System.Text;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public static async Task Run(JObject eventGridEvent, ILogger log)
{
    log.LogInformation(eventGridEvent.ToString());

    string requestUri = $"{eventGridEvent["data"]?["requestUri"]?.Value<string>()}";
    if(!string.IsNullOrEmpty(requestUri))
    {
        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Add("Authorization", Environment.GetEnvironmentVariable("AzureServiceBus_token"));
            var response = await client.DeleteAsync(requestUri);

            // status & headers
            log.LogInformation(response.ToString());

            // message body
            log.LogInformation(await response.Content.ReadAsStringAsync());
        }
    }

    await Task.CompletedTask;
}
1
votes

Azure Functions can run on either a Consumption Plan or a dedicated App Service Plan. If you run in a dedicated mode, you need to turn on the Always On setting for your Function App to run properly. The Function runtime will go idle after a few minutes of inactivity, so only HTTP triggers will actually "wake up" your functions. This is similar to how WebJobs must have Always On enabled.

For more information, see Always On in the Azure Functions Documentation.

The timeout duration of a function app is defined by the functionTimeout property in the host.json project file. The following table shows the default and maximum values in minutes for both plans and in both runtime versions:

enter image description here

You can read more about cold start here.

https://azure.microsoft.com/en-in/blog/understanding-serverless-cold-start/

HTTP trigger will help in your case y warming up your instance for sure but ideal way for 24/7 type of requirement is to use dedicated App Serice plan. Hope it helps.