Abstract
This paper discusses the thorough examination of
the challenges and solutions associated with the Microservices design patterns.
Microservices have transformed the software development sector by encouraging
modularity, scalability and maintainability, which enables businesses to react
to shifting consumer needs and technology breakthroughs faster. The study's
main research question explores the major implementation challenges, including
inter-service communication, data consistency and security and provides
possible solutions to address these challenges. It also provides a thorough analysis of several
microservices patterns, including Decomposition design patterns, Integration
patterns and Database patterns. This
paper is therefore meant to be more development-environment centered and
infrastructure agnostic. Developers
and architects who wish to concentrate on code, patterns and implementation
specifics will find this part most interesting.
Keywords: Micro Services, Design patterns, API Gateway, Decomposition
pattern, Integration pattern, Database patten, monolithic.
1. Introduction
1.1. Microservice Architecture:
Microservices architecture, as the name
suggests, is a method of developing a server application as a collection of
discrete services. Thus, while the front end can also use a microservices
design, the back end is the primary focus of this strategy. Every service
operates in a separate process and engages in communication with other
processes via protocols including AMQP, WebSocket’s and HTTP/HTTPS.
To succeed in today's unstable,
uncertain, complex and ambiguous world, business-critical enterprise
applications must offer changes quickly, often and consistently. Consequently
organizations are split up into small, loosely connected, cross-functional
teams. Every team delivers software using DevOps techniques. It uses continuous
deployment specifically. Before being deployed into production, the team's
stream of frequent, minor changes is tested by an automated deployment
pipeline. By enabling teams to deploy each microservice as needed, the goal is
to enable developers to use microservices to accelerate application releases.
2. What Makes Businesses Use Microservices
Architecture?
The majority of businesses begin by
building their infrastructures as either a single monolith or a number of
closely related monolithic applications. The monolith performs a variety of
tasks. A single, coherent piece of application code contains all of the
programming for those features. It's challenging to decipher the code for these
functions because it's all tangled together. A single feature addition or
modification in a monolith can cause the entire application's code to break.
This turns any upgrade-no matter how basic-into a costly and time-consuming
procedure. Programming gets increasingly complex as upgrades are made, until
scaling and upgrades are nearly impossible.
As time goes on, businesses are unable to modify their coding further without
beginning anew. The procedure quickly becomes too much to handle and businesses
may end up stuck with outdated practices for a long time after they ought to
have upgraded.
3. What are the fundamental ideas of Microservices
architecture?
Autonomous: By operating independently, each service removes the issues brought
on by interdependence. Increased deployment flexibility is also made possible
by this.
3.1.
Resilience: The other services remain unaffected in
the event that one goes down. The capacity of a system to bounce back quickly
from malfunctions and keep working.
3.2.
Scalability: The ability of services to immediately increase or decrease in
response to demand maximizes cost and resource allocation.
3.3.
Decentralization: Independent development teams can
increase productivity and speed time to market.
Fault
tolerance: To maintain a consistent user experience,
the system keeps running even if one or more services go down.
3.4. Monitoring: High
performance, security and availability of the infrastructure and services are
guaranteed through ongoing monitoring and health checks. Several levels of
security are designed and implemented, including secure communication,
authorization, authentication and secret management.
3.5.
DevOps integration: Quick delivery of high-caliber services is
guaranteed by incorporating DevOps into microservices architecture.
3.6.
Lazy Loading: Incoming traffic can be split equally among servers by the design.
This enhances performance and avoids overloads.
Purpose: To manage
data effectively from one or many different services. This pattern includes “Database
Per services”, “Shared Database per Service”, “CQRS”, “Event Sourcing”, “Saga
pattern”.
3.11.
Cross-Cutting Concern Patterns:
Purpose: To
uniformly handle specific capabilities throughout the system, such as logging,
tracing and monitoring across several microservices. This pattern includes
“External Configuration”, “Service Discovery Pattern”, “Circuit Breaker Pattern”,
“Blue-Green deployment Pattern”.
3.12.
Problems and fixes when choosing a design pattern:
Problem
#1: An application must be divided into smaller
components in order to transition to micro services. Which design pattern
facilitates the division of an application into smaller services?
Fix: One
method is to decompose by business capability. Using the business capability
pattern to break down an application into smaller services can be advantageous. Because
business capabilities are often stable, this pattern leads to stability.
However, the capability to recognize each unique company’s skill is essential
to its success.
Sample: For
instance, HealthCare company’s business capabilities are mainly classified as Healthcare
Clinical delivery, Patient Driven Management, HealthCare Research, Strategy, Finance
& Accounting, Human Resources, Marketing & Sales, Enterprise Support
and Governance & Compliance.
The phrase "code smell" refers
to imperfections in design and coding techniques. “God class” is a type of code
smell occurs when functionalities are distributed unevenly throughout large
classes. A number of services will share these classes. To break down further
small pieces, “Decompose by Subdomains” will be very helpful. By dividing the
primary domain into smaller domains, Domain Driven Design helps achieve this
"decompose by subdomains."
Sample: For instance, above in Health Care company’s one of the business capabilities
is “Patient Driven” which can be broken into further as “Patient Management”, “Payer
Management”, “Partner Management”, “Service Level Management”,” Medical Billing
Management”, “Patient Lead Management”. Each micro service would be bound
independently with its own logic.
Problem
#2: The current live legacy application follows the
traditional monolithic design and it is expected to be divided into smaller
components in order to transition to micro services. Which design pattern
facilitates the division of an application into smaller services?
Fix: The best approach is Strangler Pattern alias Vine pattern as the
name mentions, vine strangles around the tree, micro service wrapped around the
existing application. Strangler Pattern allows to create a new service and functions
along with the existing monolith application service next to each other. A
microservice application expands whereas a monolith application shrinks with
time. With the help of this design, it is possible to move features and
data from the monolith to the new microservices without affecting user
experience.
Problem
#3: What kind of design pattern will work best for
a company that deals with a large volume of customers at once?
Fix: To deal large volume of customers at once, Bulkhead pattern works
best. Because it resembles the sectioned partitions of a ship's hull, the
bulkhead design got its name. It functions by dividing an application's
components into distinct sections. The others can still work even if one fails.
A significant level of traffic from one service may use up all database
connections, making it impossible for other services to access the database. Limiting
the number of connections accessible to each service through the implementation
of a bulkhead pattern ensures that no single service may create a bottleneck. This
entails segmenting the system into distinct resource pools, such as database
connections or network connections, in microservice architecture. By doing
this, we can lessen the effect of any one failure, which makes it simpler to
isolate and recover from disasters.
Problem
#4: How can we manage failures graciously and
prevent cascade service failures?
Fix: Additionally, for improved fault isolation, it can be used with the
circuit breaker pattern. Circuit breaker pattern exactly works same as circuit
breaker switch. A circuit breaker switch works by interrupting the
electrical current flow when it exceeds a predetermined limit causing the
contacts to separate and break the circuit, thus protecting the system from
damage due to overload or short circuit. Likewise, the link to failed services
is disconnected by this pattern. In order to keep protected calls from being
made and left "hanging," any calls to the breaker are either
redirected to another service or result in an error default message. For a
predetermined "timeout" period, this occurs. This prevents service
failures from cascading and allows for gentle handling of failures.
Three states are handled in circuit
pattern like Open, closed, Half open. When the number of failures surpasses the
threshold, a circuit breaker pattern is in open state. In this state, the
microservice does not execute the intended function but instead returns errors
for the calls. A circuit breaker is in its default condition when it is in closed state
and all calls are handled normally. A very ideal state to be expected by the
users. A circuit breaker stays in a half-open position as it looks for
underlying issues. While some calls might receive a regular response, others
might not. The reason for the circuit breaker's initial flip to this state will
determine this.
Problem
#5: What kind of design pattern should be used to call several
microservices and manage numerous protocols?
Fix: In order to solve the aforementioned problem, the API gateway
pattern acts as a reverse proxy between client apps and the services, offering
a single-entry point for many microservice calls. The pattern also
shields the client from having to understand how services have been divided,
which is another benefit. This design pattern allows developers to
separate client apps from internal microservices, allowing for the use of a
partially unsuccessful request. This guarantees that a single unresponsive microservice
won't cause an entire request to fail. The encoded API gateway does this by
using the cache to either deliver a correct error code or an empty response.
Furthermore, API gateway patterns can handle important functions like SSL
termination, authentication and caching, which improves the security and
usability of application. It may also convert one protocol request to another
protocol and vice versa.
Problem
#6: Which design pattern aids in formatting the data and responses from
reusable microservices that can change based on the client?
Fix: Aggregator
pattern helps in the process of combining data from several providers and
sending the final response to the customer. Before returning the
data, a composite microservice will call all necessary microservices, combine
the data and change it.
Additionally, an API gateway can aggregate the data and
divide the request among several microservices before delivering it to the
customer. Selecting a composite microservice is advised if any business logic
is to be used. Otherwise, the tried-and-true method is the API gateway.
Problem
#7: Which design pattern can be used to create a
user interface (UI) page or screen that shows data from several services?
Fix: Client-Side
UI composition type helps to resolve above mentioned issue. Every UI team has
the ability to create a client-side UI element, that implements or correlates
to a certain microservice. The UI team is in charge of creating page skeletons
or skeleton user interfaces for different services by constructing pages that
are made up of various service-specific UI elements. Many JS frameworks help to
do the same. It becomes simpler and easier to maintain UI development.
Problem
#8: When an organization handles different clients
like Web application, mobile application and third-party applications. How are
the individual services accessed by the different clients of a
microservices-based application?
Fix: Design patterns like API gateway / Backend for frontends can be
considered. When we choose API gateway, it will act as a single-entry point for
all clients. The Backends for Frontends pattern is a variant of this design.
For every type of client, a distinct API gateway is defined.
4. Conclusion
The key takeaway is that no specific
technology, architecture pattern or style is appropriate in every circumstance.
The majority of major websites are switching from monolithic to microservice
architectures. It has a distinct set of problems that need to be solved, just
like any other software.
A successful microservice workflow can be achieved by
putting in place the right architecture, process tools and design patterns.
5. References