To enable the adoption of the IaaS and PaaS services, a change in how the applications are designed and architected needs to be made.
The model of designing enterprise applications on a base platform (read: application server) meant that the heavy lifting of the application's scalability and availability was the responsibility of the platform. Enterprise developers would focus on using the standardized JEE patterns and developing components (Presentation, Business, Data, and Integration) to build fully functional and transactional applications. The extent to which the application could be scaled was limited by the abilities (node clustering and distributed caching) of the underlying platform:
Monolithic application
A business application built as a monolithic application is typically characterized by the following factors:
- The entire application logic is packaged into a single EAR file
- The application reuse is derived by sharing JARs
- Application changes are planned months in advance, typically in a big push once a quarter
- There is one database that encompasses the entire schema for the application
- There are thousands of test cases that signify the amount of regression
- The application design, development, and deployment requires coordination among multiple teams and significant management
With the advent of social interactions and mobile users, the scale of application users and data started increasing exponentially. Enterprises soon found that the platform was becoming a bottleneck in terms of the following issues:
- Business agility: The operational cost of managing the application platform and making constant changes to the features/functionalities was getting hampered because of the monolithic nature of the application. Even for a small feature change, the entire cycle of regression tests and deployment across server clusters was eating into the overall speed of innovation.
The mobile revolution meant that the problem was not just at the channel layers, but also percolated down to the integration and systems of record layers. Unless enterprises fixed the problem across these layers, the ability to innovate and be competitive in the market would be under threat.
- Cost: To handle the increased demand, the IT Operations team were adding new server instances to handle the load. However, with each new instance, the complexity was increasing along with license costs (that depended on the number of cores). Unlike the Facebooks of the world, enterprise cost per user was increasing with every user acquisition.
At this time, enterprises started looking at open source products and how modern applications are getting built in consumer-facing companies serving millions of users, handling petabytes of data, and deploying to the cloud.
Consumer-facing companies encounter these hurdles early in their life cycle. Lots of innovation led to the design and development of new open source products, as well as design patterns for cloud computing.
In this context, the whole premise of service-oriented architecture (SOA) was looked at and enterprises investigated how the application architecture could adopt principles of designing autonomous services that are isolated, discrete, and could be integrated and composed with other services. This has led to the rise of the microservices model, which adapts and integrates very well with the cloud services model, where everything is available as a service and as an HTTP endpoint.
Microservices is a specialization of and implementation approach for service-oriented architectures (SOA) used to build flexible, independently deployable software systems
– Wikipedia
Microservices are designed and developed, keeping in mind that a business application can be built by composing these services. The microservices are designed around the following principles:
- Single-responsibility principle: Each microservice implements only one business responsibility from the bounded domain context. From a software point of view, the system needs to be decomposed into multiple components where each component becomes a microservice. Microservices have to be lightweight, in order to facilitate smaller memory footprints and faster startup times.
- Share nothing: Microservices are autonomous, self-contained, stateless, and manage the service state (memory/storage) through container-based encapsulation models. The private data is managed by a service and there is no contention on the data from any other service. Stateless microservices scale better and start faster than stateful ones, as there is no state to be backed up on shutdown or activated on startup.
- Reactive: This is applicable for microservices with concurrent loads or longer response times. Asynchronous communication and the callback model allow optimal utilization of the resources, resulting in better availability and increased throughput of the microservices.
- Externalized configuration: This externalizes the configurations in the config server, so that it can be maintained in hierarchical structure, per environment.
- Consistent: Services should be written in a consistent style, as per the coding standards and naming convention guidelines.
- Resilient: Services should handle exceptions arising from technical reasons (connectivity and runtime), and business reasons (invalid inputs) and not crash. Patterns, such as circuit breakers and bulk headers, help isolate and contain failures.
- Good citizens: Microservices should report their usage statistics, the number of times they are accessed, their average response time, and so on through the JMX API or the HTTP API.
- Versioned: Microservices may need to support multiple versions for different clients, until all clients migrate to higher versions. There should be a clear version strategy in terms of supporting new features and bug fixing.
- Independent deployment: Each of the microservices should be independently deployable, without compromising the integrity of the application:
Moving from a monolithic to a microservices-based application
The microservices' design, development, and deployment considerations are covered in detail in the subsequent chapters We will see how to build services for an e-commerce product. I am sure everyone is quite familiar with e-commerce and will understand the product requirements easily.