dcsimg

Why Do You Need Microservices?

Our “Microservices Masterclass” is a series of articles on microservices architecture (MSA), starting with the needs and motivations of microservices and moving on to the shortcomings of monolithic architecture and also covering microservices design patterns, pitfalls of microservices, major microservices infrastructure components, containers, native microservices, cloud platforms, messaging layers, security, and logging.

We will provide the readers with Obelix, a microservices architecture reference implementation. You may use this as the starting point for your microservices architecture. You may also directly use this as a reference implementation for your microservices strategy and/or as code to learn and implement the microservices architecture for your organization.

Types of Software Architectures

The textbook of software architecture may want to classify the types and evolution of software architectures into multiple types and sub-types. But for all practical purposes, the four types below will be the most important types of software architecture that a modern-day software architect will need to be able to identify. Almost all modern enterprise and software product architecture can be classified into one of the following:

  • Monolithic Software Architecture: As the name suggests, monolithic architecture is virtually a single block of components to serve all the application requests. It is one of the forms that has existed ever since software development and software engineering came into the world. It may be used for distributed or non-distributed applications. Usually, in a monolith, the implementation consists of various layers to achieve the functionalities as per the application requirements. Even though it may have a few asynchronous components or functionalities - for all purposes, you can imagine it to be a monolithic block or centralized block, consisting of various layers to achieve the end goal. A few types of monolithic architecture include 2-tier, 3-tier, or n-tier applications.
  • Service-Oriented Architecture (SOA): Service-oriented architecture took the thought process of software architecture to a more decentralized, loosely coupled interaction between components to serve application requests. Mostly, the initial uses for SOA were for disparate enterprise systems interacting through a shared interaction mechanism called the enterprise bus. Service-oriented architectures can be thought of as a coarse-grained decentralization of components to achieve an end goal. The service-oriented architecture was bulky and heavyweight but was able to serve the purpose of a coordinating set of services/systems (possibly monolithic themselves).
  • Microservices Architecture (MSA): The architecture that is state of the art and has caught on to almost all enterprises and every medium to large software development project is the microservices architecture (MSA). The core thought behind MSA involves true decentralization of the services or the application and more fine-grained splitting or division of application services into individual services of their own. MSA brings in a newer and complex form of infrastructural services to aid in the real ownership of respective infrastructural responsibility. Though it has its own set of disadvantages (this will be discussed later in this series of articles), it allows for independent scaling and 'selling' of services to a customer or any external stakeholders.

Shortcomings of the Monolithic Systems

Monolithic systems are built by a single focused team that may be geographically dispersed. The architecture, layer-wise or feature-wise, might mimic the way development teams of varying specialties are organized. Most of the time, these teams will have the same broad skill set or technology stack. This does not truly allow a team to completely concentrate on a problem or a feature (in-whole). Also, there is a chance within the same organization that people of different skills or technologies might want to come together in an organization to build application features or components. Each of them may want to layer their individual components to their own specific needs/ecosystem. This is not possible with monolithic systems.

Benefits of Microservices

With the advent of microservices, the new promise of truly allowing development teams to focus on their specific components or services irrespective of the technology stack, layering (specific architecture), and database (not just schema). This allows global teams to concentrate on their development lifecycles without the need to coordinate with other teams except for common components, interaction mechanisms, or infrastructure services.

Coupling

The systems built with the monolithic thought process are more tightly coupled across layers or across components - since they reside on the same 'server function' most of the time - services or components are more tightly coupled. Even though by building with correct solid and OOP paradigms - they may still be considered to be more tightly coupled as a result of being packaged in the same binary.

With microservices, each of the services can be made truly independent of each other and thereby really 'loosely coupled.' They can be deployed on disparate servers and can even be considered to be built with any technology that is the expertise of the company/unit.

Scalability

Monolithic systems, especially those with lots of nonfunctional requirements related to performance and also scalability are usually marred by symmetric scalability, which can lead to system resources being shared between the services that do not have scalability requirements and ones that have scalability requirements. Usually, systems need asymmetric scalability wherein the core features or core business logic services may have higher scalability requirements, and the helper or non-core features might have less hardware or memory requirements.

With the advent of microservices, one of the greatest advantages is that it allows us to architect/design systems that can scale independently at every level - whether it is service level or at the database level or any resource that may otherwise have been shared. This allows us to plan and size for systems accurately and more cost-effectively.

The organization will get every penny’s worth through accurate sizing/scaling exercises. The resources will be allocated and used as the actual customer usage reflects in the budgeting. However, the challenges introduced by communication mechanisms within microservices or distributed database transaction mechanisms may result in negative outcomes. The performance and scalability of microservices will be discussed in detail in my future articles in this series.

Availability

Availability needs to be thought of as a different technical requirement from others; with monolithic systems, if a server comes down, almost always, the entire application stops responding. Even if it is highly available, there may be times at peak load where the system stops responding or slows down to the point that the application is actually unavailable.

In the microservices world, the independent nature of services now allows us to plan for high availability much easier, and fault tolerance, failure recovery, and retry on fail mechanisms are now more automated and efficient. Also, the failure of a single service will never bring the entire application down. For mission-critical systems, this is a great advantage as parts of systems or features will keep responding even though some services have failed in the ecosystem.

Performance

Performance in the monolithic world will have to be planned for the entire application. This also includes performance testing. Just as described earlier, the parts of the system that are under severe load might actually cause the entire system to slow down. Though this point is very similar to the scalability point, you always have to note that the performance of a system or API will have to be accounted for separately from the scalability. Though the same reasons apply, it has to be thought of as localized or as API-specific.

In theory, the performance of microservices should ideally be greater than the same monolithic service since the application/feature will now have its own server, database, and resources - but since the microservices have a lot of infrastructural services and the communication overhead may result in a negative outcome. This topic will be discussed further in my future articles - for now, you have to simply note that if a monolithic service were to be built on a database per microservice kind of architecture, it is bound to perform much higher than its monolithic counterpart.

Infrastructure

Monolithic systems never had standardized infrastructure components, even though, with the advent of SOA, a few of the infrastructural components started finding their place in software architecture. Most of the time, infrastructural abilities for service availability, failure recovery, configuration management, service health, service discovery, security infrastructure, messaging mechanisms, logging, and log analysis, were mostly built or incorporated in a very custom way per project or product.

With microservices, there is a widely agreed-upon standardized architecture that is a master blueprint for organizations to follow for their microservices architecture. Even if companies were to adopt/implement only partial infrastructural components from the standard it would still mean that there is uniformity in the way microservices are implemented. There are many of the actual infrastructural frameworks that are available for these standardized requirements. The organization or the microservices architect may use any of them based on their suitability to their environment.

Business

The most important outcome of engineering is almost always that the innovation or the product is more easily available or sellable to the market. The greatest advantage is that business <> engineering bridge is more complicated or may need more time to deliver on in the case of monolithic architecture. Also, the product is almost always thought of as a complete unit and will be sold as a subscription or fixed price or pay-as-you-go mechanism. Usually, when a customer wants only a few of the services or features, business teams would bundle it up - but under the hood, the product would still be one large unit of code/binary.

Inherently, with the microservices architecture, the business advantage is the ability to independently sell/size the services and the associated hardware or resources for a customer. The business can plan for a subscription, pay as you go, or fixed price at a service level much more 'easily.' Also, any new service or even custom services can be easily planned, independently built, and incorporated into the entire product ecosystem at a customer or product level.

Challenges of Microservices Architecture

The Following are some challenges of the microservices architecture.

Overhead

The setup of microservices requires more effort as there are a lot of infrastructural, architectural pieces as part of a complete microservices architecture. For example: API gateway, circuit breaker, discovery server, config server, health monitoring, vault service, token service, logging, and auditing are just a few of the initial infrastructural services required to correctly implement a complete microservices architecture in the enterprise.

High Skill

There is a high skill level required, especially in terms of experienced senior architects, DevOps, and developers who can now understand the change in the development paradigm. Also, this may either increase the development time or development costs or both.

Complexity

One of the most important disadvantages of microservices is the complexity involved. Even though the point is captured in the above 2 points - it still requires a mention on its own. The interplay of the plethora of infrastructural services along with the actual application microservices may create an unending cycle(s) of complexity.

Redundancy

During development, the architects and lead engineers may need to keep a watch on making sure that there is no duplication of code, configuration, or any other effort that may already have been developed by another team. This starts becoming a greater concern when there are geographically distributed teams and focusing entirely on their own set of business or product deliverables. Though some very trivial code duplication may be inevitable, discipline will be required to isolate and group common functionality or code together correctly.

Data Duplication

One of the greatest challenges is data duplication. Most inexperienced architects and engineers may end up in such situations. It is because the thought that was required to build monolith data access and creation cannot now be used for microservices. The mechanism to maintain data integrity and data consistency in a product to make sure that there exists a correct 'single version of the truth' needs to be planned, architected, and infused into the design.

Communication

The communication between the external world and microservices or within microservices may fail. This could be due to multiple reasons, including network failure and service unavailability. In any case, the communication between microservices is critical and is tough to set up and maintain. It also requires constant monitoring of the health and performance of each of the microservices. Partial failures are actually an advantage of microservices - but still, the monitoring, failure detection, failure handling, and simply the internal/external communication can be quite an overhead in the implementation of microservices.

Maintenance

So, once the initial part is over, even if the microservices strategy and implementation turn out to be a success, it still means a heavy hit on the pocket for maintenance. Even though all of the current generation organizations rely on an external cloud provider, it still means more expenditure on hardware, 'software,' cloud, DevOps engineers. Also, the total cost of ownership of such an infrastructural masterpiece is only bound to increase as more abstractions are added over time, the maintenance itself could be a complicated process.

True Cloud Applications and Containerization

AWS, GCP, Azure, and More

At the turn of the decade (the 2010s) came the dawn of the true cloud-native applications. The most popular of the cloud providers being Amazon Web Services (AWS), Microsoft Azure, and Google Cloud Platform. The paradigm of deployment now moved from an on-premise, hosted to a public cloud or private cloud. Now, microservices slowly caught up to speed by around the 2015s, and the adoption has never stopped since as of 2021. Almost 50%* of the world's applications are being built using the microservices architecture (either entirely, partially, or hybrid) and true cloud-native applications and microservices are not exactly equivalent, but the cloud providers are able to provide most of the infrastructure in their own ecosystem. So, we can say the true cloud-native environments have ready support for microservices infrastructure and architecture.

Docker, Kubernetes, and ++

Docker, Kubernetes, and other container technology tools are a modern-day enhanced equivalent of a web server or application server, except that the function is to now vendor neutrally deploy images and allow multiple DevOps functions to be carried out on the images, such as configuration, clustering, or communication.

Docker and Kubernetes have become the gold standard for enterprise software, with Docker being popular for containerization and Kubernetes for container orchestration. Docker and Kubernetes will allow monolithic architecture to be deployed as well, but the containerization paradigm has a one to one correlation with microservices as both allow an independent nature of DevOps, and when combined with true cloud providers they become the modern-day development and operations engine for deployment, maintenance, containerization, cloud, scalability, availability, failure recovery, configuration, communication, and more infrastructural concerns.

The State of Microservices in 2021

As of 2021, as a principal software architect in the software industry - being part of almost four companies that have adopted or started to adopt microservices (especially using Spring Boot, Spring Cloud, Spring Data, Spring-Security, Netflix OSS, and Java/Java EE stack in my area of expertise) - I can now safely say that almost all companies have either moved to or are in the process of moving to microservices. This is due to the obvious advantages and promises of microservices.

Every technology in history has brought with it a newer set of problems that engineers and architects have solved in their newer counterparts. Nevertheless, microservices are one such engineering innovation. In the future articles in this series, we shall look at the issues that are faced by microservices themselves in detail. The below categorization clearly shows that microservices and their hybrid varieties are slowly displacing monolithic and SOA architectures in the enterprise and in software development projects.