To understand the advantages of microservices architectures today, it’s critical to understand where it all started from.
Monolithic applications
Initially each application, residing on a single server, comprised three layers:
- Presentation
- Application/business logic
- Database
These layers were built in a single, intertwined stack located on a single, monolithic server in a data center. This pattern was common across every industry vertical and technology architecture. Generally speaking, an application is a collection of code modules that serve a particular function—for example, a database, various types of business logic, graphics rendering code, or logging.
In this monolithic architecture, users interacted with the presentation layer, which talked to the business logic layer and the database layer, and information then traveled back up the stack to the end user. Although this was an efficient way to organize an application, it created many single points of failure, which could result in long outages if there was a hardware failure or code bug. Unfortunately, “self-healing” did not exist in this structure. If a part of the system was damaged, it would need to be repaired by human intervention in the form of a hardware or software fix.
Furthermore, scaling on any one of these layers meant purchasing an entire new server. You had to purchase a monolithic application running on a single server and segment a portion of users over to the new system. This segmenting resulted in silos of user data that had to be reconciled by nightly batch reports. Thankfully, client need became thinner as webpages and mobile applications became more popular, so new methods of application development began to take shape.
Service-oriented architecture (SOA)
By the mid-2000s, the architectures began to change so that various layers existed outside a single server and as independent service silos. Applications were designed to integrate these services by using an enterprise service bus for communication. This approach lets administrators independently scale these services by aggregating servers through proxy capabilities. The approach also enabled shorter development cycles by allowing engineers to focus on only one part of the application service structure. Decoupling services and allowing independent development required the use of APIs, the set of syntax rules that services use to communicate with each other.
SOAs also coincided with the rise of the virtual machine (VM), which made physical server resources more efficient. Services could be deployed much more quickly on smaller VMs than previous monolithic applications on bare-metal servers. With this combination of technologies, better high-availability (HA) solutions were developed, both within the services architecture and with the associated infrastructure technologies.
Microservices
Today, cloud microservices break down the SOA strategy further as a collection of granular functional services. Collections of microservices combine into large macroservices, providing even greater ability to quickly update the code of a single function in an overall service or larger end-user application. A microservice attempts to address a single concern, such as a data search, logging function, or web service function. This approach increases flexibility—for example, updating the code of a single function without having to refactor or even redeploy the rest of the microservices architecture. The failure points are more independent of each other creating creating a more stable overall application architecture.
This approach also creates an opportunity for microservices to become self-healing. For example, suppose that a microservice in one cluster contains three subfunctions. If one of those subfunctions fails, the is being repaired. With orchestration tools such as Kubernetes, self-healing can occur without human intervention; it occurs behind the scenes, is automatic, and is transparent to the end user.
Microservices architectures have come into use along with Docker containers—a packaging and deployment construct. VM images have been used as the deployment mechanism of choice for many years. But containers are even more efficient than VMs, allowing the code (and required code libraries) to be deployed on any Linux system (or any OS that supports Docker containers). Containers are the perfect deployment vector for microservices. They can be launched in seconds, so they can be redeployed rapidly after failure or migration, and they can scale quickly to meet demands. Because containers are native to Linux, commodity hardware can be applied to vast farms of microservices in any data center, private cloud, or hybrid multicloud.
Microservices have been intertwined with cloud-native architectures nearly from the beginning, so they have become indistinguishable from each other in many ways. Because microservices and containers are so abstracted, they can be run on any compatible OS (usually Linux). That OS can exist anywhere: in the public cloud, on premises, in a virtual hypervisor, or even on bare metal. As more development is done in the cloud, cloud-native architectures and practices have migrated back into on-premises data centers. Many organizations are constructing their local environments to share the same basic characteristics as the cloud, enabling a single development practice across any locations, or cloud-native anywhere. This cloud-native approach is made possible and necessary by the adoption of microservices architectures and container technologies.