Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The core components of this architecture are a web front end that handles client requests and a worker that does resource-intensive tasks, long-running workflows, or batch jobs. The web front end communicates with the worker through a message queue.
The following components are commonly incorporated into this architecture:
One or more databases
A cache to store values from the database for quick reads
A content delivery network to serve static content
Remote services, like email or Short Message Service (SMS), that non-Microsoft service providers typically provide
An identity provider for authentication
The web and worker are both stateless, and session state can be stored in a distributed cache. The worker handles long-running work asynchronously. Messages on the queue can start the worker, or a schedule can run it for batch processing. The worker is optional if the application has no long-running operations.
The front end might include a web API. A single‑page application can consume the web API by making AJAX calls, or a native client application can consume it directly.
When to use this architecture
The Web-Queue-Worker architecture is typically implemented by using managed compute services like Azure App Service or Azure Kubernetes Service.
Consider this architecture for the following use cases:
Applications that have a relatively simple domain
Applications that have long-running workflows or batch operations
Scenarios where you prefer managed services over infrastructure as a service (IaaS)
Benefits
An architecture that's straightforward and easy to follow
Deployment and management with minimal effort
Clear separation of responsibilities
Decoupling of the front end and worker through asynchronous messaging
Independent scaling of the front end and worker
Challenges
Without careful design, the front end and worker can become large monolithic components that are difficult to maintain and update.
If the front end and worker share data schemas or code modules, there might be hidden dependencies.
The web front end can fail after persisting to the database but before sending messages to the queue, which causes consistency problems because the worker doesn't do its part of the logic. To mitigate this problem, you can use techniques like the Transactional Outbox pattern, which require routing outgoing messages to first loop back through a separate queue. The NServiceBus Transactional Session library supports this technique.
Best practices
Expose a well-designed API to the client. For more information, see API design best practices.
Automatically scale to handle changes in load. For more information, see Autoscaling best practices.
Cache semistatic data. For more information, see Caching best practices.
Use a content delivery network to host static content. For more information, see Content delivery network best practices.
Use polyglot persistence when appropriate. For more information, see Understand data models.
Partition data to improve scalability, reduce contention, and optimize performance. For more information, see Data partitioning best practices.
Web-Queue-Worker on App Service
This section describes a recommended Web-Queue-Worker architecture that uses App Service.
Download a Visio file of this architecture.
Workflow
The front end is implemented as an App Service web app, and the worker is implemented as an Azure Functions app. The web app and the Functions app are both associated with an App Service plan that provides the virtual machine (VM) instances.
You can use either Azure Service Bus or Azure Storage queues for the message queue. The previous diagram uses a Storage queue.
Azure Managed Redis stores session state and other data that requires low-latency access.
Azure Content Delivery Network is used to cache static content like images, CSS, or HTML.
For storage, choose technologies that best fit your application's needs. This approach, known as polyglot persistence, uses multiple storage technologies in the same system to meet different requirements. To illustrate this idea, the diagram shows both Azure SQL Database and Azure Cosmos DB.
For more information, see Baseline highly available zone-redundant web application and Build message-driven business applications with NServiceBus and Service Bus.
Other considerations
Not every transaction must go through the queue and worker to storage. The web front end can do simple read and write operations directly. Workers are designed for resource-intensive tasks or long-running workflows. In some cases, you might not need a worker at all.
Use the built-in autoscale feature of your compute platform to scale out the number of instances. If the load on the application follows predictable patterns, use schedule-based autoscaling. If the load is unpredictable, use metrics-based autoscaling.
Consider putting the web app and the Functions app into separate App Service plans so that they can scale independently.
Use separate App Service plans for production and testing.
Use deployment slots to manage deployments. This method lets you deploy an updated version to a staging slot, then swap over to the new version. It also lets you swap back to the previous version if there's a problem during the update.