Four Steps to Running Microservices in Azure
Microservices architectures are becoming widely adopted, replacing the traditional monolithic application architecture. It is common to build microservices applications using public cloud infrastructure—on Azure this involves services like Azure Service Fabric, Azure Kubernetes Service (AKS) and Azure Functions.
Azure provides infrastructure, managed services and end-to-end developer tools that can help you build new microservices applications and migrate legacy applications to a microservices model.
Azure Microservices Infrastructure: 3 Managed Services to Help Deploy
Let’s review the three core services used to deploy microservices applications on Azure. These are also three compute options for microservices—service fabric, containers and serverless.
Below we discuss the functional aspects of each service, a note: Pricing is also a key consideration, but is outside the scope of this article. Refer to this detailed guide to Azure pricing. To better understand security aspects, see this post covering Azure security.
Azure Service Fabric can run both in Azure and on-premises using Microsoft Windows Server. It provides:
- Service life cycle management—automatic service deployment and upgrades, service discovery, health monitoring, healing failed services and more.
- Flexible deployment—microservices can be deployed in containers or as operating system processes with full orchestration features.
- Infrastructure APIs—provides extensive control over infrastructure via APIs controlling ASP.NET Core and Reliable Actors/Services.
Service Fabric enables a four-step migration from monolithic applications to microservices:
- Use containers to host existing code in Service Fabric
- Add new microservices
- Split the legacy application into microservices while extending original functionality
- Build new microservices applications
Azure Kubernetes Service (AKS)
A common choice for microservices architectures is to deploy microservices in containers. AKS is a managed service that makes it easy to set up Kubernetes in the Azure cloud. Kubernetes orchestrates, deploys and manages Docker container clusters.
The figure below shows the architecture of AKS for microservices deployments. AKS deploys a Kubernetes cluster, taking responsibility for master nodes while allowing users to manage worker nodes. Kubernetes clusters run containers representing backend services and additional containers running utility services such as Prometheus for monitoring. Azure Storage services provide persistent storage outside the Kubernetes cluster.
In this setup, you can use an Azure load balancer to route traffic to the Kubernetes Ingress module and pass traffic information to enable smart routing of requests across the cluster. Azure Pipelines lets development teams push new updates and automatically deploy them to production clusters using Helm charts.
Azure Functions allows you to adopt a serverless approach to microservices. The unit of work is a serverless function driven by real-time events instead of an entire container.
Azure Functions executes code based on event triggers and terminates a function when the code finishes executing or another event occurs. You don’t need to maintain infrastructure unnecessarily—Azure Functions only bills you during actual runtime.
You can build microservices exclusively with serverless features driven by messaging or event streaming infrastructure like Azure Event Grid. Alternatively, you can use serverless functionality to complement the applications deployed in containers.
A useful capability of Azure Functions is that it is based on an open source engine and can be downloaded and deployed locally. This makes it possible to deploy serverless capabilities in hybrid cloud scenarios.
A Four-Step Process for Building a Microservices Architecture in Azure
Microsoft has published a design pattern that specifies how to build microservices applications in Azure while following the 12-factor app principles.
1. Domain Analysis
It is important to define the roles and responsibilities of each subsystem in the microservices structure and ensure that there are no hidden dependencies or tight couplings between services.
Microsoft advises that microservices should perform business functions, not technical functions such as data access, analytics or messaging. The Azure design pattern encourages users to adopt a domain-based design (DDD) framework to formally define the business problem (“bounded context”) that it is trying to solve. Each microservice should be designed based on a well-defined bounded context with no dependence on other microservices.
2. Choosing an Azure Compute Option
Azure provides three compute options for microservices, each with relative advantages and disadvantages:
- Service Orchestrator—using Azure Service Fabric—provides Reliable Collections, which are scalable, high-performance cloud applications that behave like single computer applications. Most suitable for building stateful services.
- Container Orchestrator—using Azure Kubernetes Service—provides good isolation of resources between different tasks and easy portability between physical resources. Most suitable for building microservices with high scalability and reliability requirements.
- Function-as-a-Service—using Azure Functions—abstracts management of infrastructure and can save operating costs in many scenarios. Most suitable for small services that process streaming events.
You must also consider persistency options for stateful microservices. There are a variety of managed Azure database services, both SQL and NoSQL, cloud-based file shares via Azure file storage and Azure blob storage.
3. Designing APIs for Microservices
Here are a few important considerations when building APIs for your microservices architecture:
- REST vs. RPC—For public APIs, prefer to use REST over HTTP. For backend APIs, which microservices use to connect to each other, prefer RPC, which provides faster serialization and optimal payload size. Keep communication to a minimum to prevent APIs from becoming chatty.
- Formal definition of APIs—It is important to have a formal definition of your APIs to enable automated documentation, auto-generated client code and for generating security rules. Use the Interface Definition Language (IDL) in RPC APIs and OpenAPI for REST APIs.
- API gateway—Use an API gateway to translate backend RPC APIs to REST.
- Languages—When coding your API, keep in mind that RPC API frameworks only support Java, Python, C++ and C# while REST APIs can support any language.
4. Select a Design Pattern for Your Microservices
Finally, choose a design pattern for each microservice. Most microservices can be classified into one of these design patterns:
- Ambassador—Enables client connectivity tasks like routing, monitoring and logging.
- Façade layer (anti-corruption layer)—Bridging traditional monolithic applications and microservices.
- Bulkhead—Partitions critical system resources such as CPU, memory and connection pools.
- Backend for frontend—Provides separate backend services for different types of clients.
- Gateway aggregation, offloading or routing—Aggregating requests for multiple services into a single request, offloading shared functions to a gateway or providing an endpoint to deliver requests to multiple services.
- Strangler—Gradually replacing features with new, refactored services.
- Sidecar—Helper components running as a separate container.
The figure below illustrates how these archetypes work together in a complete microservices architecture. Microsoft provides detailed documentation on how to build each type of microservice in Azure.
In this article I covered the three key services that support microservices deployment in Azure:
- Service Fabric—Lets you deploy services and manage their life cycle, both in Azure and on-premises
- Azure Kubernetes Service (AKS)—Lets you manage containerized microservices within fully managed Kubernetes clusters
- Azure Functions—Lets you deploy and manage microservices as serverless functions
Finally, I described Microsoft’s recommended process for deploying a microservices application:
- Analyzing the business domain and defining microservice functionality
- Selecting from the above compute options
- Designing your APIs
- Selecting a design pattern—ambassador, façade layer, bulkhead, etc.
I hope this will be helpful as you evaluate the use of Azure for existing and greenfield microservices applications.