loading...

. . . . . .

Let’s make something together

Give us a call or drop by anytime, we endeavour to answer all enquiries within 24 hours on business days.

Find us

504, Gala Empire,
Driver-in Road, Thaltej,
Ahmedabad – 380054.

Email us

For Career – career@equalefforts.com
For Sales – sales@equalefforts.com
For More Info – info@equalefforts.com

Phone support

Phone: +91 6357 251 116

Microservice Architecture

  • By Jitin Jadavra
  • April 11, 2024
  • 38 Views

What are Microservices?

Microservices are a modern software development approach in which the application code is delivered in small, manageable pieces that operate independently of one another. It’s a method to build a distributed system that emphasizes fine-grained services, is loosely coupled, and focuses on a single business responsibility.

Introduction to Microservices

Although there is no official definition of microservices, they are independently releasable services modeled around a business domain.

Let’s take a look back at the history of software systems. IT organizations have built these systems based on team expertise and responsibility over the years. Microservices architecture has become a popular way to build software systems in recent years.

The three-layer architecture is designed to separate responsibility between the three teams. It allows each tier to run on its infrastructure, which can be developed and updated independently without affecting the other tiers. However, this architecture becomes less effective as software systems become more complex, resulting in a monolithic application that requires changes in all tiers whenever an update is made.

It is necessary to design the system based on business functionality so that each team is responsible for delivering specific business functionality, as the scope of change is spread across all three tiers.

“Microservice Architecture” is a new approach that overcomes the limitations of traditional software architecture. A system implementing microservices architecture will look like this:

Principle of Microservices

A microservice application must follow the principle of microservices as mentioned below:

Independently Deployable
Independent deployable means a service can be deployed without deploying related services. It’s the most important principle. Achieving it requires building loosely coupled services with stable contracts and evolving interfaces.

Modeled Around Business Functionality
Microservices should be based on business functionality, not technical implementation. Domain-driven design is a useful approach to structure code and define service boundaries.

Owns the State
Each service should own its state. They should not share a database. If a service needs data owned by another, it should ask for it. This opens the door for polyglot persistence. One service can use RDBMS, while another can use a document database.

Share Information using Well-Defined Interfaces
Microservices must share information via well-defined interfaces such as REST, gRPC, GraphQL, or Messaging Queue to relate services, complementing the “Own the state” principle.

Key Components of a Microservices Architecture

Core Services
Each service is a self-contained unit of functionality that can be developed, tested, and deployed independently of the other services.

Service registry
A service registry is a database of all the services in the system, along with their locations and capabilities. It allows services to discover and communicate with each other.
All the microservices in our microservice project will register to the service registry, and the API gateway will discover the particular microservice hostname and port using the service registry so that the API gateway can allow that request to a particular microservice.

API Gateway
An API gateway is a single entry point for all incoming requests to the microservices. It acts as a reverse proxy, routing requests to the appropriate service and handling tasks such as authentication and rate limiting.

Whenever the client sends a request to the API gateway and then an API gateway will route that request to the relevant microservices.

The client can be a web application, a mobile application, or a desktop application and whenever a client wants to consume the REST APIs of backend services, the client has to first send a request to the API gateway, and then the API gateway will route that request to the relevant microservice.

  1. Config Server: This config server component will externalize the configuration of microservices.
  2. Distributed Tracing: To maintain the logs or complete log hierarchy for a particular HTTP call from start to end, we can use distributed tracing.
  3. Security: We can implement centralized security in the API gateway.
  4. Message Bus: A message bus is a messaging system that allows services to communicate asynchronously with each other. This can be done through protocols like HTTP, RabbitMQ, or Kafka.
  5. Monitoring and Logging: Monitoring and logging are necessary to track the health of the services and troubleshoot problems.

Microservices Communication

There are different ways to make a REST API call from one microservice to another Microservice. For example, we can use a RestTemplate or WebClient or Spring cloud-provided open feign library. There are two ways of Microservices Communications.

Synchronous Communication
The client sends a request and waits for a response from the service. The important point here is that the protocol (HTTP/HTTPS) is synchronous and the client code can only continue its task when it receives the HTTP server response. We can use RestTemplate or WebClient or Spring Cloud Open Feign library to make a Synchronous Communication between multiple microservices.

Asynchronous Communication
The client sends a request and does not wait for a response from the service. The client will continue executing its task – It doesn’t wait for the response from the service. We can use Message brokers such as RabbitMQ and Apache Kafka to make Asynchronous Communication between multiple microservices. Spring provides the RestTemplate class. This allows you to send HTTP requests to a RESTful server and fetch data in many formats – such as JSON and XML.

Characteristics of a Microservices Architecture

Split into numerous components
Software built using a microservices architecture is, by definition, broken down into numerous component services. Each service can be created, deployed, and updated independently without compromising application integrity. The entire application can be scaled up by tweaking a few specific services instead of taking it down and redeploying it.

Robust and resistant to failure
It is not easy for an application built using a microservices architecture to fail. Of course, individual services can fail, undoubtedly affecting operations. After all, numerous diverse and unique services communicate with each other to carry out operations in a microservices environment, and failure is bound to occur at some point.
However, in a correctly configured microservices-based application, a function facing downtime should be able to reroute traffic away from itself while allowing its connected services to continue operating. It is also easy to reduce the risk of disruption by monitoring microservices and bringing them back up as soon as possible in case of failure.

Simple routing process
Microservices consist of intelligent components capable of processing data and applying logic. These components are connected by ‘dumb wires’ that transmit information from one element to another.
This simple routing process is the opposite of the architecture used by some other enterprise applications. For example, an enterprise service bus utilizes complex systems for message routing, choreography, and the application of business rules. Microservices, however, simply receive requests, process them, and produce an appropriate output to be transferred to the requesting component.

Decentralized operations
Microservices leverage numerous platforms and technologies. This makes traditional centralized governance methods inefficient for operating a microservices architecture.
Decentralized governance is better suited for microservices as developers worldwide create valuable tools to solve operational challenges. These tools can even be shared and used by other developers facing the same problems.
Similarly, a microservices architecture favors decentralized data management, as every microservice application manages its unique database. Conversely, monolithic systems typically operate using a centralized logical database for all applications.

Built for modern businesses
Microservices architecture is created to focus on fulfilling the requirements of modern, digital businesses. Traditional monolithic architectures have teams work on developing functions such as UI, technology layers, databases, and server-side logic. Microservices, on the other hand, rely on cross-functional teams. Each team takes responsibility for creating specific products based on individual services transmitting and receiving data through a message bus.

Advantages and Disadvantages of Microservices

When deciding whether to use a microservice architecture, it’s important to consider your requirements as each system has its advantages and disadvantages. Let’s see some advantages and disadvantages of microservices.

Advantages of Microservices

Scaling
Microservices are easily scalable because they can be deployed independently. Scaling only the necessary service reduces the overall cost.

Resiliency
Microservices are more resilient as faults are contained within a single service.

Faster Releases
Microservices enable quick changes in production as delivery contention is reduced to one responsible team.

Small Codebase
Microservices codebases are composed of smaller and more manageable chunks of code as opposed to monolith codebases. This makes it easier to maintain and deploy the microservices.

Resource Requirement
Unlike monolith, this can run on standard hardware. However, operational costs can be high due to dedicated computing requirements for each service.

Development & Deployment

  • Gives developers the freedom to independently develop and deploy services
  • Can be developed by a fairly small team
  • Code for different services can be written in different languages (though many practitioners discourage it)
  • Easy integration and automatic deployment (using open-source continuous integration tools like Jenkins, Hudson, etc.)
  • Easy to understand and modify for developers, thus can help a new team member become productive quickly
  • Developers can make use of the latest technologies
  • The code is organized around business capabilities
  • Starts the web container more quickly, so the deployment is also faster
  • When change is required in a certain part of the application, only the related service can be modified and redeployed – no need to modify and redeploy the entire application
  • Better fault isolation: if one microservice fails, the other will continue to work (although one problematic area of a monolith application can jeopardize the entire system)
  • Easy to scale and integrate with third-party services
  • No long-term commitment to the technology stack

Disadvantages of Microservices

Complexity
Microservice architecture inherits the complexities of distributed systems and should be designed with the fallacies of the distributed system in mind from day one.

Monitoring and Troubleshooting
It can be challenging to manage and monitor multiple services without access to appropriate tools.

Reporting
It is easier with monolith architecture since data is available in a single database. However, with microservice architecture, data is spread across multiple services, making reporting more difficult.

Cost
Microservices may increase costs due to additional hardware, network, and software requirements. Adopt them only if the benefits outweigh the cost.

Development & Deployment

  • Due to distributed deployment, testing can become complicated and tedious – and often hinders some of the scaling benefits of microservices
  • Increasing number of services can result in information barriers
  • Additional complexity as the developers mitigate fault tolerance, network latency, and a variety of message formats as well as load balancing
  • Being a distributed system, it can result in duplication of effort
  • When the number of services increases, integration and managing whole products can become complicated
  • Developers have to deal with the additional complexity of a distributed system
  • Developers have to implement a mechanism of communication between the services
  • Handling use cases that span more than one service without using distributed transactions is not only tough, it requires cooperation between different teams

Challenges with Microservices Architecture

There are a few challenges with microservices architecture.

Data Consistency
Each microservice owns its state, so consistency is restricted to a single service. But our operation spans multiple services, so if a transaction fails in one service, our system should be able to undo the entire operation.

Complex Testing
Microservices make unit testing easier, but integration testing is challenging due to distributed components, making it impossible to test an entire system from developers’ machines.

Unclear Domain
Breaking a microservice without a clear domain or prematurely breaking it can lead to a “Distributed Monolith” which has the drawbacks of both microservices and single-process monoliths.

Signs of the distributed monolith

Change in one service causes re-deployment of other services.

  • Service shares database.
  • Long release processes and rigorous release planning.
  • Panic before releases.

Best Practices for Microservices

Use async communication
Use asynchronous communication to avoid tightly coupled components and promote loose coupling among services.

Maintain backward compatibility
To change things smoothly, make sure your API updates are backward compatible. If you make a breaking change, offer a new version while still supporting the old one. This way, users can switch to the new version when they’re ready.

Version your releases
It is important to use semantic versioning to indicate the type of changes made with each release. This will help the consumer of your service to know if a release is major, minor, or patch.

Use a Circuit breaker to avoid cascading failure
A circuit breaker pattern can be applied to microservices, where a software circuit breaker stops sending requests to a non-responsive or slow service, isolating faults and preventing cascading failures to other dependent services.

Design Patterns for Microservices Architecture

Decomposition Design Patterns

By utilizing decomposition design patterns, breaking down a large application into smaller microservices becomes an achievable task. This strategic approach not only simplifies the process but also ensures a more efficient and effective system.

  • Decompose By Business Capability: We can develop a microservice for a specific business capability, which is a business activity designed to create value.
  • Decompose By Subdomain: Decompose your application using business capabilities. If you encounter “God Classes,” define services that correspond to subdomains of Domain-Driven Design (DDD). DDD’s domain refers to the application’s problem space – the business, and it is made up of several subdomains, each representing a unique aspect of the business.
  • Decompose By Strangler: We can define a microservice using the strangler pattern in two types of services: those that display the existing behavior in Monolith, and those that implement new features.
  • Bulkhead Pattern
  • Sidecar Pattern

Integration Design Patterns

When building a large, complex application with microservice architecture, different microservices may use various protocols such as REST or AMQP. However, allowing clients to access each microservice without worrying about protocols and other complexities can be challenging. Integration design patterns help handle these issues, such as obtaining the results of many services in a single call. Some common examples of integration design patterns include an API Gateway Pattern, Aggregator Pattern, Proxy Pattern, Gateway Routing Pattern, Chained Microservice Pattern, Branch Pattern, and Client-Side UI Composition Pattern.

  • API Gateway Pattern
  • Aggregator Pattern
  • Proxy Pattern
  • Gateway Routing Pattern
  • Chained Microservice Pattern
  • Branch Pattern
  • Client-Side UI Composition Pattern

Database Design Patterns

Database design patterns are crucial for creating a structured database architecture for microservices. The microservice architecture includes loosely linked microservices developed individually in an agile manner for continuous delivery/deployment. Database design patterns focus on the database structure and architecture in a microservices-based application.

  • Database per Service
  • Shared Database per Service
  • CQRS
  • Event Sourcing
  • Saga Pattern

Observability Design Patterns

Observability design patterns cover logging, performance metrics, and other factors to monitor applications effectively. Services generate logs with standardized information, which are used to identify and troubleshoot application issues.

  • Log Aggregation
  • Performance Metrics
  • Distributed Tracing
  • Health Check

Cross-Cutting Concern Design Patterns

Cross-cutting Concern Design Patterns address service discovery, external configurations, deployment situations, and interactions with infrastructure or third-party services. Examples of infrastructure services are service registry, message broker, and database server. Third-party services include payment, email, and messaging services.

  • External Configuration
  • Service Discovery Pattern
  • Circuit Breaker Pattern
  • Blue-Green Deployment Pattern

Conclusion

The three-tier architecture was commonly used in IT organizations but couldn’t handle increasing project complexity. Monolith applications are difficult to scale and prone to delivery issues. Microservices are better suited to complex business domains, with each service responsible for a single business functionality end-to-end. Microservices offer faster delivery, scalability, and resiliency over monolith.

Leave a Reply

Your email address will not be published. Required fields are marked *