This document describes the Priority Queue Pattern example from the guide Cloud Design Patterns.
- Microsoft .NET 6
- Microsoft Visual Studio 2019 or later version
- Azure Functions Core Tools version 4x
Ensure that you have installed all of the software prerequisites.
The example demonstrates operational aspects of applications running in Windows Azure. Therefore, you will need to use the monitoring tools in order to understand how the code sample works. You must ensure that the Azure Functions in the solution are configured to use the diagnostics mechanism. If not, you will not see the trace information generated by the example.
This example shows how you can implement priority queues by using Service Bus Topics and Subscriptions. A timer triggered Azure Function is responsible for sending messages to a topic. It assigns a priority to each message. The receiving Azure Functions read messages from subscriptions that have the corresponding priority. In the example, the PriorityQueueConsumerHigh Azure function can scale out to 200 instances, whereas the PriorityQueueConsumerLow worker runs only with one instance. This simulates high priority messages being read from the queue more urgently than low priority messages.
You can either run this example locally from Visual Studio or you can run it by deploying it to Azure.
-
From the Azure Portal, provision an Azure Service Bus Namespace.
-
Once the Service Bus Namespace is created, add a new topic to it, name it "messages" (leave all the properties default).
-
Once the topic is created, add a new subscription to it, name it "highPriority", set "10" as Max delivery count.
-
Add a new filter of type "SqlFilter" to the subscription, name it "priorityFilter".
-
Set the expression Priority = 'highpriority' in the filter body.
-
Click on "Save changes".
-
Add another subscription to the topic, name it "lowPriority", set "10" as Max delivery count.
-
Add a new filter of type "SqlFilter" to the subscription, name it "priorityFilter".
-
Set the expression Priority = 'lowpriority' in the filter body.
-
Click on "Save changes".
-
Start Visual Studio.
-
Open the solution you want to explore from the subfolders where you downloaded the examples.
-
Edit the local.settings.json file in all the projects and change the ServiceBusConnection__fullyQualifiedNamespace setting by changing the placeholder "<service_bus_namespace>" to your Azure Service Bus Namespace name.
-
If you want to run the example in the local Windows Azure emulator:
- Set the PriorityQueueSender project as startup.
- Press F5 in Visual Studio to start the example running. The function will start sending messages to the topic, every 30 seconds.
- Stop the execution, change the startup project to either the PriorityQueueConsumerHigh or PriorityQueueConsumerLow
- Press F5 in Visual Studio to start the execution of the consumer function
- In the Azure Functions Core Tools Console, you can view the diagnostic information generated by Trace statements in the code.
-
If you want to run the example on Azure:
-
On every function project, right click and select publish.
-
Select "Azure" as publishing target.
-
Select "Azure Function App" as specific target.
-
In the Functions instance step, select you Azure Function app or create a new one using the link button.
-
Since your app settings are different you need to deploy every Azure Function in a separate Azure Funcion App.
-
You can select an existing resource group and storage account or create new ones.
-
In "Hosting" section, click on the the three dots (...) in the upper right corner.
-
Select "Manage Azure App Service Settings".
-
You need to add these two settings:
-
ServiceBusConnection__fullyQualifiedNamespace:
Set the value to: <service_bus_namespace>.servicebus.windows.net Replacing the placeholder with you Azure Service Bus Namespace name.
-
-
Once the Functions are deployed you need to restrict the maximum number of instances your app service consumption can scale out to:
- From the portal go to the Function App that contains the "PriorityQueueConsumerLow" Azure Function
- Navigate to Scale Out on the left menu
- On the App Scale Out dialog set the "Enforce Scale Out Limit" to "Yes"
- Set the Maximum Scale Out Limit to 1 instance
You don't need to modify these settings for the Function App containing the "PriorityQueueConsumerHigh" Azure Function since the default setting is 200; this ensures that high priority messages are read from the queue more quickly than low priority messages.
-
Now you need to configure the managed identities role assignments:
In the Azure portal, navigate to the Azure Service Bus Namespace that was provisioned in the first step. Select Access Control (IAM). This is where you can view and configure who has access to the resource. Click Add and select add role assignment. From the list, select "Azure Service Bus Data Sender", click Next In "Assign access to", radio button list, select "Managed identity" Click on "Select members", the "Select Manage identities" dialog will show up In the Managed Identity dropdown list select "Function App" Find the PriorityQueueSender function app click on it Click "Select" On the main dialog, click "Review + Assign" For the Azure Consumer Function Apps, repeat the process but in this case use the role "Azure Service Bus Data Reader"
-
Once the Functions are deployed you can configure monitoring by following these steps:
- From the Azure Portal, go to the Function App Service
- Click on "Functions" and select the azure function
- From the "developer" left menu click on "Monitor"
- Turn on application insights
- Refresh the screen
- Once refreshed you will see two tabs, "invocation" and "logs"
- From the invocations tab you can see the twenty most recent function invocation traces. For more advanced analysis, run the query in Application Insights.
- From the logs tab you can see the logging information that your functions are sending.
-