In this article, we will study how the Microservices Architecture pattern is a natural evolution of SOA and the enterprise innovations that entail the adoption of the Microservices architecture.
At Readify, we have been assisting clients to deliver innovative solutions for over a decade. Many of our previous customers have been businesses generating most of their revenue online. Due to recent innovations in technology and increased competition, an organisations application can experience massive changes in volume, consumption models and customer usage. Most clients engage with us to guide them through the journey of solving a familiar problem:
How to maintain agility and innovation in a highly fluid market without impacting your customers.
The Microservices Journey
The Microservices approach to solution delivery evolved as a response to the challenges faced by the application economy when rolling out new applications and integrations at high velocity.
Much of the need for Microservices can be attributed to the growth of the technology since the late 1990’s. Prior to this, mainframes were the only acceptable means of handling data processing requirements of businesses, tasked with mission-critical workloads of payroll and ledger processing. In general, mainframe developers have been developing monolithic applications that have little to no re-usability.
While the world of software was stuck on the monolithic design, we witnessed the growth of processing powers at the rate predicted by Moore’s law (https://en.wikipedia.org/wiki/Moore%27s_law//). With the increase in hardware capacities, businesses requirements started to become more involved. Despite this, increased complexities resulted in software producing diminishing returns on investment as the costs to maintain the solutions became significantly higher than the returns.
Adding complexity to existing monoliths continued until we reached the point of software crisis (https://en.wikipedia.org/wiki/Software_crisis). The industry identified that the obvious solution to the problem was to deconstruct the monoliths into smaller reusable services, that could then be integrated to build a cohesive application. This new diversified architecture technique came to be known as a Service Oriented Architecture (SOA). In the following diagram, you can see the typical SOA implementation of an enterprise.
A typical SOA application involves a set of services linked to one another using an integration platform such as an ESB (Enterprise Service Bus). The services that connect through ESB publish a set of well-known contracts that the other services can use. SOA is an enterprise-wide architecture, which tries to normalize the communication between the various services. Using the ESB, SOA provides flexible orchestration capability to inter-service communication. Since SOA has a wide approach towards architecture, the participant services are generally not very granular and may be demarcated by organizational units rather than by domain. SOA also requires services to be tightly coupled with the ESB, with any change to an individual service contract requiring changes to be made to the ESB. The need to make combined changes can result in many of the dependent participant services being deployed in a monolithic manner.
Although SOA helps organizations achieve flexibility, it doesn’t address the need for organizations to evolve rapidly and utilise the latest innovations in continuous integration and deployment that helps drive agility. This is often termed “devops” which refers to the practice of development and operational teams work together in a highly cohesive manner
Recently, the Microservices architecture has started to gain traction as an alternative to SOA. While this model of architecture shares many commonalities with SOA such as being service based and granularity of services, both vary from one other, from an architectural and organizational view.
To understand the architectural difference between SOA and Microservices, let’s redraw the previous SOA architecture diagram using the Microservices architecture principles.
The Microservices architecture focuses on the segregation of services by domain and not by the organizational entities. Unlike SOA, the scope of Microservices architecture is more narrow and limited to a project. The Microservices architecture offers a higher degree of flexibility than SOA by supporting fast deployment and independent development of individual Microservices. Unlike SOA, services are typically not implemented by the various organizational units but by teams in the same project. Due to the high independence of Microservices, individual Microservices enjoy the ability to be deployed independently. More often than not, Microservices bring along their User Interface (as well, which can be integrated into a composite UI application along with the UI of other Microservices.
Using the Microservices architecture, individual teams get the ability to utilize the DevOps tools to reach their full potential, flesh out features, and fix independently from other teams. The architecture helps an individual developer become more productive as they no longer need to absorb the whole application to contribute to it. With happy teams and developers, the organizations immediately start reaping the benefits of adopting Microservices.
Microservices do make the participating services simple for DevOps and enhance agility but does it reduce the complexity of an application? The simple answer to this question is no, as although Microservices do increase the simplicity of an application in parts, the application as the sum of its parts remains complex. By adopting Microservices, we are only pushing the complexity from our application to the infrastructure. For customers using Microservices, moving their applications to the cloud makes the most sense. as with cloud we have the ability to manage that complexity through programmable infrastructure, infrastructure automation and the ubiquitous nature of the cloud.
Building Microservices typically requires solving complex problems such as service discovery, partitioning, replication, and scale. There are several orchestration services available now that can handle Application Lifecycle Management (ALM) of Microservices such as Docker Swarm, Mesosphere, CoreOS, and Kubernetes. However, the need to manage Microservices as a platform offering or Platform as a Service (PaaS) gave birth to Microsoft Azure Service Fabric which as well as it’s many services acts as a cluster manager.
Microsoft itself has used Azure Service Fabric for many years to host its planet-scale services such as Azure SQL Database, Azure IoT hub, Skype for Business, Cortana, and Intune.
An organization that intends to adopt Microservices needs to innovate in several areas. Since Microservices delivery entails a higher complexity, an organization needs to improve not just technologically, but also in the areas of operations and infrastructure. The following are the areas that an organization adopting Microservices needs to innovate in.
Microservices are distributed systems which require a network to communicate with each other. With the innovations in processor technology, we now have servers that can process millions of instructions per millisecond. However, latency in network and serialization and deserialization of messages between Microservices may negatively impact the performance of the application despite using efficient servers. For example, on an average, the network latency in a data centre is around 0.5ms. A server with a 3GHz processor can process 1.5 million instructions in this period.
An organization needs to make a trade-off between bonding the services together or hosting them across nodes. There are several innovations that an organization can implement to improve performance, such as, segregating Microservices through processes or containers rather than separating them by hardware. Network optimizations such as connecting nodes to the same cluster switch can also improve the performance of a Microservices application.
A chatty Microservices application in which Microservices frequently communicate with one another indicates that the architecture of the system needs to be revisited and improved.
Microservices should almost never share component, as the simple act of sharing common code can induce coordination and coupling between Microservices, leading to tight organizational coupling. Code redundancy between Microservices is an acceptable measure to avoid close organizational linkages. Any helper libraries and interfaces offered by a Microservice should be optional and not a requirement to use the Microservice.
Adhering to the shared-nothing approach in Microservices will yield benefits in terms of delivery agility and organizational dependence.
First of all, the issue of unreliable communication should be solved at the technical level. In a Microservices application, failing to communicate with an individual Microservice should not bring the system to a halt but should compensate for the failure by degrading the functionality.
Secondly, the infrastructure hosting the Microservices should be optimized to be highly available. If an enterprise is hosting Microservices on premise, then it needs to assess the cost associated with building such infrastructure and balance the cost with desired QoS.
Rather than solving all of the challenges associated with an enterprise application using a shared technology base, individual Microservices can be built using autonomous technology stacks. Although this makes a holistic understanding of an application complex from an operations perspective, often such an understanding is not necessary.
Certain aspects of individual Microservices should be made uniform using shared technology or common behavior. For example, a consistent logging framework or uniform logging format should be used to make fault detection and remediation simpler. To simplify operations, a common technical basis such as Docker, (Java Virtual Machine) , etc. may be decided upon without setting the programming language.
The architecture of a Microservices application should follow the principles of Domain Driven Design (DDD). The faulty identification of a domain may lead to the movement of functionalities around Microservices which is often difficult to accomplish. The Microservice architecture influences not only the application but the organization and delivery velocity, which in turn affects the time-to-market of an application. Once the domains have been recognized, individual Microservices within a domain can adjust the architecture as the knowledge of the domain increases.
Microservices application requires a multitude of hosting systems to ensure complete technology independence. Using a large number of hosts requires automation and appropriate infrastructure to generate and manage many virtual machines. An organization would need to adopt the following DevOps practices to embrace Microservices completely.
Each Microservice requires pipeline so that it can be brought to production independently from other Microservices. Manual management of multiple CD pipelines in a Microservice application is hard, requiring automation tools such as Visual Studio Team Services. Varying configurations of individual CD pipelines can lead to increased costs, therefore, the configurations should be standardized.
Microservices applications require a more complex monitoring solution than monoliths. A Microservice monitoring solution requires system logs to be interleaved with application logs so that an elaborate view of the application is available to help expedite debugging in case of failures.
Unlike monoliths, Microservices need to be version controlled at all times due to clients and other Microservices depending on changes applied to the contracts exposed by Microservices. Independent version control decouples Microservices from each other as the various Microservices need not be brought into production together.
We realize that Microservices are a great pattern to deliver modern applications while fulfilling the goal of increased velocity of application releases. Microservices can fulfill that aim by decomposing the application into small autonomous services that can be independently deployed. Microsoft Azure Service Fabric (https://azure.microsoft.com/en-au/services/service-fabric/) is a proven platform that abstracts hard distributed system problems such as reliability, scalability, management, and latency so that developers and organizations can focus on building Microservices. However, a Microservices architecture also brings along some challenges which proven canonical patterns can help mitigate.
In our recently released title, Microservices with Azure, my colleague Namit and I have documented several Microservices architecture patterns that can help Solution Architects understand Microsoft Azure Service Fabric in detail and design, and implement Microservices. The title is available on Amazon (amazon.com/dp/1787121143) and our publisher’s website (https://www.packtpub.com/virtualization-and-cloud/microservices-azure). We hope that this title helps ease the journey of your organization to Microservices and cloud.
I regularly write about Azure, Microservices and, other nascent technologies on my blog https://rahulrai.in.
Author: Rahul Rai, 3rd October 2017
Originally posted at: https://rahulrai.in/