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.
An architecture style is a family of architectures that share specific characteristics. For example, N-tier is a common architecture style. More recently, microservice architectures are starting to gain favor. Architecture styles don't require the use of specific technologies, but some technologies are better suited for certain architectures. For example, containers are well-suited for microservices.
We identified a set of architecture styles that are commonly found in cloud applications. The article for each style includes the following components:
- A description and logical diagram of the style
- Recommendations for when to choose this style
- Benefits, challenges, and best practices
- A recommended deployment that uses relevant Azure services
A quick tour of the styles
This section gives a quick tour of the architecture styles that we identified, along with some high-level considerations for their use. This list isn't exhaustive. Read more details in the linked articles.
N-tier
N-tier is a traditional architecture for enterprise applications that divides an application into logical layers and physical tiers. Each layer has a specific responsibility, and layers manage dependencies by only calling into layers below them. Typical layers include presentation, business logic, and data access.
N-tier architectures are well-suited for migrating existing applications that already use a layered architecture. This approach requires minimal changes when moving to Azure and supports mixed environments with both on-premises and cloud components. But the horizontal layering can make it difficult to introduce changes without affecting multiple parts of the application, which limits agility for frequent updates.
Web-Queue-Worker
Web-Queue-Worker is an architecture that consists of a web front end, a message queue, and a back-end worker. The web front end handles HTTP requests and user interactions, while the worker performs resource-intensive tasks, long-running workflows, or batch operations. Communication between the front end and worker occurs through an asynchronous message queue.
This architecture is ideal for applications with relatively simple domains that have some resource-intensive processing requirements. It's easy to understand and deploy with managed Azure services like App Service and Azure Functions. You can scale the front end and worker independently to provide flexibility in resource allocation. But without careful design, both components can become large and monolithic.
Microservices
The Microservices architecture decomposes applications into a collection of small, autonomous services. Each service implements a single business capability within a bounded context and is self-contained with its own data storage. Services communicate through well-defined APIs and can be developed, deployed, and scaled independently.
Microservices enable teams to work autonomously and support frequent updates with higher release velocity. This architecture is well-suited for complex domains that require frequent changes and innovation. But it introduces significant complexity in areas such as service discovery, data consistency, and distributed system management. Success requires mature development and DevOps practices, which makes it more suitable for organizations that have advanced technical capabilities.
Event-driven architecture
Event-driven architectures use a publish-subscribe model where event producers generate streams of events, and event consumers respond to those events in near real time. Producers and consumers are decoupled from each other, with communication happening through event channels or brokers. This architecture supports both simple event processing and complex event pattern analysis.
Event-driven architectures excel in scenarios that require real-time processing with minimal latency. Some examples are IoT solutions, financial trading systems, or applications that need to process high volumes of streaming data. Event-driven architectures provide excellent scalability and fault isolation but introduce challenges around guaranteed delivery, event ordering, and eventual consistency across distributed components.
Big data
Big data architectures handle the ingestion, processing, and analysis of data that's too large or complex for traditional database systems. These architectures typically include components for data storage (like data lakes), batch processing for historical analysis, stream processing for real-time insights, and analytical data stores for reporting and visualization.
Big data architectures are essential for organizations that need to extract insights from massive datasets, support predictive analytics using machine learning, or process real-time streaming data from IoT devices. Modern implementations often use managed services like Microsoft Fabric to simplify the complexity of building and maintaining big data solutions.
Big compute
Big compute architectures support large-scale workloads that require hundreds or thousands of cores for computationally intensive operations. The work can be split into discrete tasks that run across many cores simultaneously, with each task taking input, processing it, and producing output. Tasks can be either independent (embarrassingly parallel) or tightly coupled requiring high-speed communication.
Big compute is essential for simulations, financial risk modeling, scientific computing, engineering stress analysis, and 3D rendering. Azure provides options like Azure Batch for managed big compute workloads or HPC Pack for more traditional cluster management. These architectures can burst capacity on-demand and scale to thousands of cores when needed.
Architecture styles as constraints
An architecture style places constraints on the design, including the set of elements that can appear and the allowed relationships between those elements. Constraints guide the "shape" of an architecture by restricting the universe of choices. When an architecture conforms to the constraints of a particular style, certain desirable properties emerge.
For example, the constraints in microservices include:
- A service represents a single responsibility.
- Every service is independent of the others.
- Data is private to the service that owns it. Services don't share data.
When you adhere to these constraints, you gain a system that lets you take the following actions:
- Deploy services independently.
- Isolate faults.
- Push more frequent updates.
- Introduce new technologies into the application more easily.
Each architecture style has its own trade-offs. Before you choose an architectural style, it's essential to understand the underlying principles and constraints. Without that understanding, you risk creating a design that superficially conforms to the style without realizing its full benefits. Focus more on why you're selecting a specific style than on how to implement it. Be practical. Sometimes it's better to relax a constraint than to chase architectural purity.
Ideally, the choice of architectural style should be made with input from informed workload stakeholders. The workload team should start by identifying the nature of the problem that they're solving. They should then define the key business drivers and the corresponding architecture characteristics, also known as nonfunctional requirements, and prioritize them. For example, if time to market is critical, the team might prioritize maintainability, testability, and reliability to enable rapid deployment. If the team has tight budget constraints, feasibility and simplicity might take precedence. Selecting and sustaining an architectural style isn't a one-time task. It requires ongoing measurement, validation, and refinement. Because changing architectural direction later can be costly, it's often worthwhile to invest more effort upfront to support long-term efficiency and reduce risks.
The following table summarizes how each style manages dependencies, and the types of domain that are best suited for each style.
| Architecture style | Dependency management | Domain type |
|---|---|---|
| N-tier | Horizontal tiers divided by subnet | Traditional business domain. Frequency of updates is low. |
| Web-Queue-Worker | Front-end and back-end jobs, decoupled by asynchronous messaging. | Relatively simple domain with some resource-intensive tasks. |
| Microservices | Vertically (functionally) decomposed services that call each other through APIs. | Complicated domain. Frequent updates. |
| Event-driven architecture | Producer or consumer. Independent view for each subsystem. | Internet of Things (IoT) and real-time systems. |
| Big data | Divide a huge dataset into small chunks. Parallel processing on local datasets. | Batch and real-time data analysis. Predictive analysis by using machine learning. |
| Big compute | Data allocation to thousands of cores. | Compute intensive domains such as simulation. |
Consider challenges and benefits
Constraints also create challenges, so it's important to understand the trade-offs when you adopt any of these styles. Determine if the benefits of the architecture style outweigh the challenges, for this subdomain and bounded context.
Consider the following types of challenges when you select an architecture style:
Complexity: The architecture's complexity must match the domain. If it's too simplistic, it can result in a big ball of mud, where dependencies aren't well managed and the structure breaks down.
Asynchronous messaging and eventual consistency: Asynchronous messaging is used to decouple services and improve reliability because messages can be retried. It also enhances scalability. However, asynchronous messaging also creates challenges in handling eventual consistency and the possibility of duplicate messages.
Interservice communication: Decomposing an application into separate services might increase communication overhead. In microservices architectures, this overhead often results in latency problems or network congestion.
Manageability: Managing the application includes tasks such as monitoring, deploying updates, and maintaining operational health.