This is the first post in a series that takes a deep dive into Microservices & Azure App Services. The goal of this series is to educate you on microservices and how to apply a microservices style architecture to your new OR existing application by using Azure App Services, a newer PaaS offering to the Azure cloud.
This series will focus on components and development surrounding usage of Visual Studio 2015 & C#/.NET. Most, if not all of the services we cover in this series support more than just .NET: NodeJS, Python, Java, PHP, and more.
In a traditional sense, when you are ready to create a new application architecture, it’s not uncommon, nor wrong, to separate this out into a standard n-tier architecture: UI, Business Logic Layer (BLL), and a Data Access Layer (DAL), potentially with a Service layer, like WCF, between the UI and BLL. In the case of building our own eBay.com, this architecture would look something like this:
This architecture is sufficient in many cases and typically can last the lifetime of the application in production (depending on the client, service, etc). Scaling this architecture must be done on the X-axis, by scaling out, that is, creating more instances of the same application. Let’s think of some of the pros & cons to this architecture:
- Easy to deploy – A single ASP.NET application in a single IIS Web site
- Easy to scale – Scale up, with more hardware; Scale out, with more instances. One IIS site on each VM. “Just duplicate” what you already have.
- Easy to develop – Usually contained within Visual Studio, same technologies, shared patterns and class libraries across projects
- Requires full application deployment to deploy individual components & features
- Waste of resources and dollars by scaling out, masking actual system bottlenecks.
- Entire technology stack is locked in and pretty difficult to replace individual pieces
- Even with dependency injection, class libraries are shared across the stack and force tightly coupled layers
- Intimidating to new developers as a mature solution can be difficult to ramp up on
This traditional architecture is also known as a monolithic architecture, for the fact that it’s a large single application that removes fine grained control over components.
Introducing the microservice
In contrast to the monolith is the microservice. A small focused service who has a single responsibility. This service is a smaller component to a larger system architecture and is deployed as an application that is independant of the larger web/business/data/service/etc. By splitting these components out to individual services, we have greater control over the development, deployment, scale, etc. of the application, and can lesson our worry and focus on the other layers of the application. We can scale individual resources, or groups of individual resources, up & down as needed, split them out, or re-group as needed, using the Azure PaaS services.
Let’s consider a revisit to the monolithic architecture we saw earlier. By re-visiting the scale cube we looked at before, we would want to scaling on the Y-axis, by decomposing our application into functional responsibilities. The following is intended to be a very basic split out of the function areas that were tightly coupled in the monolith.
It’s important to note that we’re not splitting out the monolith strictly by the BLL/DAL, but on a functional basis. We could still use these n-tier approaches within each microservice, and that would be absolutely acceptable, but each tier would become significantly smaller in scope, and based upon the implementation details of the service itself, this could be overkill.
- Deploy independantly from the other services
- Scale up & out separate from the rest of the application
- Easier to ramp new sources – They can focus on a single microservice at a time
- Loosely coupled technology contracts. Each component just needs to understand HTTP & JSON. Flexibility to swap technology inside each service.
- Smaller footprint. Each service is lighter in weight compared to the monolight.
- Increased deployment complexity. It can be tricky to manage deployments of new features across services
- Increased complexity to start. This can require more code, more upfront setup to get things going.
- Eventual consistency – Impossible to manage data flows as a transaction. Distributed systems will take time to be in the same state for a given action.
- Logging and monitoring is separated and needs more attention than before.
Coming up next
In the next post of this series, we will begin our deep dive into Azure App Services and how to apply these microservice concepts and architecture into App Services’ components directly. Our deep dive will begin with Azure Web Apps.