Exploring Common Design Patterns in Microservice Architecture
image source - https://kruschecompany.com/

Exploring Common Design Patterns in Microservice Architecture

Microservice architecture is a framework that enables the construction of applications as a set of independent services, each with its own functionality and capabilities. By decoupling services from each other, the framework facilitates the independent deployment of each component, which provides a greater degree of maintainability. This allows smaller teams to work independently on building, testing, maintaining, or deploying each service, which can lead to more efficient development processes

Microservice architecture offers numerous advantages, such as enhanced flexibility and accelerated development, along with simplified deployment for larger systems. One of the significant benefits of microservices is that each service can operate using its own technology stack. This allows organizations to adopt or evolve to a unified stack in stages, which can simplify the migration process.

One of the greatest benefits of microservices is higher fault tolerance. If one service becomes unavailable, it is less likely to bring down the entire application as long as other services are designed to handle such failures. Additionally, microservices provide a flexible approach to scalability and resource allocation, as each service may have different resource requirements. This allows each service to be scaled independently, without scaling the entire system. Overall, microservices architecture can improve system reliability by providing fault tolerance and scalability.

In situations where one of the services needs to have schema updates to extend an application or to handle an unforeseen situation, microservices make it easier to do so, with data isolation to specific microservices.

Microservices are always compared with monolithic or service-oriented architecture styles. Microservices have their own challenges, and may not fit all the requirements. It depends on what we are trying to build and achieve. Microservices can become complex with many moving parts, and when we try to bring together the entire system, it may become complex.

Microservices require a different development approach and tools compared to monolithic applications. Interservice communication may throw some challenges with latency and network congestion.

Since each microservice will have its own persistence data storage, having a consistent data model across services may be challenging.

The diagram here gives the right perspective on how and where microservices are more suitable than monolithic frameworks.

No alt text provided for this image
Image Source https://martinfowler.com/bliki/MicroservicePremium.html


In this article, I will be attempting to highlight some of the very common microcservices architecture pattern that we need to know while designing a scalable robust system.

Strangler Pattern

The first pattern is the Strangler pattern, which is very useful when migrating from an existing monolithic to a microservices architecture framework. Migrating an existing monolithic production system to a microservices framework is a big challenge. It all boils down to the best decomposition pattern that an architect can consider.

The Strangler microservices pattern means gradually replacing one functionality at a time as a microservices module. In general, an API gateway will be configured to redirect specific calls to a new microservice. Once all the services are migrated, the monolithic system can be decommissioned or strangled.

In this architecture pattern, sharing the data store/model between an existing monolithic and a new microservices module will be challenging. If the existing monolithic system is simple and more minor, then the best approach is to migrate all at once.

Decompose by business capability

Another decomposition pattern is decomposing by business capability. Based on the single responsibility principle, each microservice can be decomposed based on how business separates/defines business objects to achieve better value. Cross-functional teams like business and development teams can work closely to achieve/define the business objective.

A clear definition of the domain model is key to the success of this architecture pattern.

Sidecar Pattern

Sidecar pattern, where smaller applications’ components which provides supporting features for the parent application are deployed independently. The sidecar services are created and decommissioned along with the parent services but it will be loosely coupled with the parent service. This pattern reduces complexities by abstracting the common functionality into a separate supporting microservices by avoiding duplication of implementation or code.

It is very important to have a clear understanding whether a sidecar service could work better as part of the parent service.

API Gateway Pattern

API Gateway Pattern is an integration pattern that is critical in microservices patterns. The frontend application may end up connecting to many microservices to serve the end user. This may become too complex to manage and keep track of each service during their lifecycle. An API gateway can sit between backend microservices and the frontend application, providing routing, caching, and aggregating responses to the frontend app. This can be the place where SSL termination happens, compared to at each service level. The API gateway can help in investigating any issues through logging, contain any throttling and also work as a load balancer for the backend systems.

The flip side of the API Gateway pattern is that it introduces some level of latency and can become a single point of failure. An architect can avoid having an intermediary API gateway if the microservices are very small, and the overall system caters to a smaller set of the user base.

Proxy Pattern

This is a pattern that can be considered when migrating from a monolithic system to a microservices system, which will have slightly different API calls for a specific need. The proxy in between can work as a gatekeeper and navigate the calls based on input parameters or the use case it needs to serve at the frontend. This can again be a bottleneck, so once all the systems are migrated, it can be decommissioned. But in other cases where we have to serve the same data to different channels (mobile vs web), this proxy layer will come in handy

There are couple of Database Patterns I would like to consider here are

Database Per Service

To make the microservices truly independent and loosely coupled, it is important to have a dedicated database per microservice. If any other service needs data belonging to a database, then it has to be inter-process communication through the microservices. This approach will help to scale and also to cater to different storage requirements per microservice.

This approach may increase communication between services for the smallest data needs and also needs careful design to ensure that all the data models follow certain standards that make it easy to process, consume or store data from another microservice.

CQRS

Command Query Responsibility Segregation — This pattern is used when we have different data requirements for read and write. In this approach, data modification is separated from data read. Different data storage is used for read and write. Data integrity and consistency are maintained through asynchronously updating the data from the write side of the data store to the read side of the data store (e.g., replications).

This approach ensures that the performance of data read is faster and high-availability is guaranteed. At the same time, data consistency will be weak based on the method architects will consider keeping the data up to date. This approach is not very helpful if data read and write will have the same frequency and load.

Saga

Saga pattern is basically about updating its database and then firing an event/ notification for other services to update its local database. A saga is a sequence of transactions that updates each service and publishes a message or event to trigger the next transaction step.

Saga pattern keeps the system loosely coupled and at the same time highly consistent.

On the other hand, the complexity of the number of notifications to handle or error handling in a large system with multiple microservices will be more.

Health-Check

The health check pattern is an essential pattern architects should consider to quickly identify the issue when there are multiple integration points between services. Each microservice can have a separate service to check the host status, database connectivity, or any critical logic which can give quick insight into the issue

Service Discovery Pattern

Service discovery pattern is a way for applications and services to locate each other automatically to avoid frequent configuration needs, specifically in container-based host setups where IP addresses are dynamically assigned.

There are two ways, server-side discovery, and client-side discovery. The server-side discovery allows the client application to find the services through load balancers or routers. Client-side discovery is an application querying a service registry where all the active service entries are updated.

The advantage of Server-side service discovery is that it makes the client application simpler as it does not have to implement a procedure to lookup.

The advantage of Client-side service discovery is that the client application does not have to do an extra hop to find the service

Circuite Breaker Pattern

Microservice generally calls another service to get the data. If downstream services are down, the response will not provide any result or increase the network traffic with data exchange or modification.

The requesting microservice should call a remote service via a proxy that acts like an electrical circuit breaker. When the number of consecutive failures crosses a threshold, the circuit breaker fails, and all attempts to invoke the remote service fail for a timeout period. After the timeout expires, the circuit breaker allows a limited number of test requests to pass. Then, if those requests succeed, the circuit breaker resumes regular operation. Otherwise, if there is a failure, the timeout period begins again. This pattern is suited to prevent an application from invoking a remote service or accessing a shared resource if this operation is likely to fail.

Blue-Green Deployment

The blue-green deployment pattern is used to ensure the deployment process is seamless when multiple microservices need to be deployed, patched, or upgraded.

The blue-green approach is about creating two identical instances running behind the load balancer where one of the instances could be the current prod version and the other one is new.

Using a blue/green deployment strategy increases application availability and reduces deployment risks by simplifying the rollback process if a deployment fails. Once all the testing is done, live application traffic is directed to the new instance and the old instance can be deprecated.

Conclusion

These are some of the key commonly used patterns to consider during microservice architecture be it a new implementation or migration. It is not mandatory to consider all the patterns in every implementation. Some of them may be a right one for your requirement or tech stack so it is important to evaluate and make a decision.

References

https://martinfowler.com/bliki/MicroservicePremium.html

https://docs.aws.amazon.com/whitepapers/latest/overview-deployment-options/bluegreen-deployments.html

https://towardsdatascience.com/microservice-architecture-a-brief-overview-and-why-you-should-use-it-in-your-next-project-a17b6e19adfd

I would love to double down. Lets connect. Ramananda Shetty

To view or add a comment, sign in

More articles by Ramananda Shetty

  • Apple Intelligence: "One More Thing..."

    Apple's "One more thing..

  • Apple Vision Pro - First Impression

    I had an opportunity today to experience yet another first-generation Apple device, Apple Vision Pro. Even though I was…

    4 Comments
  • Exploring ChatGPT

    Since it has been a trend for the last couple of weeks, I tried a few basic sample queries with chatGPT 3, and it…

    1 Comment
  • REST APIs and Architectural Constraints

    As developers and architects, we all come across either developing the RESTFul APIs or interfacing with one to connect…

    1 Comment
  • Eddystone - Google's Beacon Profile

    In addition to my previous post, I have few more updates from Beacon’s world. As most of us know that Apple's iBeacon…

    2 Comments
  • iBeacons - A Briefing..

    As we all know it has been an year apple announced support for iBeacons in their iOS 7 SDK. Since then there is a new…

    3 Comments

Others also viewed

Explore content categories