Sunday, October 6, 2019

Microservice Architecture and Design Patterns for Microservices


Microservice Architecture (MSA) and some Design Patterns for Microservices. Here are the four goals to consider in Microservice Architecture approaches.
  1. Reduce Cost: MSA will reduce the overall cost of designing, implementing, and maintaining IT services.
  2. Increase Release Speed: MSA will increase the speed from idea to deployment of services.
  3. Improve Resilience: MSA will improve the resilience of our service network.
  4. Enable Visibility: MSA support for better visibility on your service and network.



Decomposition Patterns

Decompose by Business Capability
Microservices is all about making services loosely coupled, applying the single responsibility principle. It decomposes by business capability. Define services corresponding to business capabilities. A business capability is a concept from business architecture modeling [2]. It is something that a business does in order to generate value. A business capability often corresponds to a business object, e.g.
  • Order Management is responsible for orders
  • Customer Management is responsible for customers
Decompose by Subdomain
Decomposing an application using business capabilities might be a good start, but you will come across so-called “God Classes” which will not be easy to decompose. These classes will be common among multiple services. Define services corresponding to Domain-Driven Design (DDD) subdomains. DDD refers to the application’s problem space — the business — as the domain. A domain is consists of multiple subdomains. Each subdomain corresponds to a different part of the business.
Subdomains can be classified as follows:
  • Core — key differentiator for the business and the most valuable part of the application
  • Supporting — related to what the business does but not a differentiator. These can be implemented in-house or outsourced
  • Generic — not specific to the business and are ideally implemented using off the shelf software
The subdomains of an Order management include:
  • Product catalog service
  • Inventory management services
  • Order management services
  • Delivery management services
Decompose by Transactions / Two-phase commit (2pc) pattern
You can decompose services over the transactions. Then there will be multiple transactions in the system. One of the important participants in a distributed transaction is the transaction coordinator [3]. The distributed transaction consists of two steps:
  • Prepare phase — during this phase, all participants of the transaction prepare for commit and notify the coordinator that they are ready to complete the transaction
  • Commit or Rollback phase — during this phase, either a commit or a rollback command is issued by the transaction coordinator to all participants
The problem with 2PC is that it is quite slow compared to the time for operation of a single microservice. Coordinating the transaction between microservices, even if they are on the same network, can really slow the system down, so this approach isn’t usually used in a high load scenario.
Strangler Pattern
Above three, design patterns that you go through were decomposing applications for Greenfield, but 80% of the work you do is with brownfield applications, which are big, monolithic applications (legacy codebase). The Strangler pattern comes to the rescue or solution. This creates two separate applications that live side by side in the same URI space. Over time, the newly refactored application “strangles” or replaces the original application until finally, you can shut off the monolithic application. The Strangler Application steps are transform, coexist, and eliminate [4]:
  • Transform — Create a parallel new site with modern approaches.
  • Coexist — Leave the existing site where it is for a time. Redirect from the existing site to the new one so the functionality is implemented incrementally.
  • Eliminate — Remove the old functionality from the existing site.
Bulkhead Pattern
Isolate elements of an application into pools so that if one fails, the others will continue to function. This pattern is named Bulkhead because it resembles the sectioned partitions of a ship’s hull. Partition service instances into different groups, based on consumer load and availability requirements. This design helps to isolate failures, and allows you to sustain service functionality for some consumers, even during a failure.
Sidecar Pattern
Deploy components of an application into a separate processor container to provide isolation and encapsulation. This pattern can also enable applications to be composed of heterogeneous components and technologies. This pattern is named Sidecar because it resembles a sidecar attached to a motorcycle. In the pattern, the sidecar is attached to a parent application and provides supporting features for the application. The sidecar also shares the same lifecycle as the parent application, is created and retired alongside the parent. The sidecar pattern is sometimes referred to as the sidekick pattern and is the last decomposition pattern that we show in the post.

Integration Patterns

API Gateway Pattern
When an application is broken down to smaller microservices, there are a few concerns that need to be addressed
  • There are multiple calls for multiple microservices by different channels
  • There is a need for handling different type of Protocols
  • Different consumers might need a different format of the responses
An API Gateway helps to address many concerns raised by the microservice implementation, not limited to the ones above.
  • An API Gateway is the single point of entry for any microservice call.
  • It can work as a proxy service to route a request to the concerned microservice.
  • It can aggregate the results to send back to the consumer.
  • This solution can create a fine-grained API for each specific type of client.
  • It can also convert the protocol request and respond.
  • It can also offload the authentication/authorization responsibility of the microservice.
Aggregator Pattern
When breaking the business functionality into several smaller logical pieces of code, it becomes necessary to think about how to collaborate the data returned by each service. This responsibility cannot be left with the consumer.
The Aggregator pattern helps to address this. It talks about how we can aggregate the data from different services and then send the final response to the consumer. This can be done in two ways [6]:
  1. A composite microservice will make calls to all the required microservices, consolidate the data, and transform the data before sending back.
  2. An API Gateway can also partition the request to multiple microservices and aggregate the data before sending it to the consumer.
It is recommended if any business logic is to be applied, then choose a composite microservice. Otherwise, the API Gateway is the established solution.
Proxy Pattern
API gateway we just expose Microservices over API gateway. I allow to get API features such as security and categorizing APIs in GW. In this example, the API gateway has three API modules:
  • Mobile API, which implements the API for the FTGO mobile client
  • Browser API, which implements the API to the JavaScript application running in the browser
  • Public API, which implements the API for third-party developers
Gateway Routing Pattern
The API gateway is responsible for request routing. An API gateway implements some API operations by routing requests to the corresponding service. When it receives a request, the API gateway consults a routing map that specifies which service to route the request to. A routing map might, for example, map an HTTP method and path to the HTTP URL of service. This function is identical to the reverse proxying features provided by web servers such as NGINX.
Chained Microservice Pattern
There will be multiple dependencies of for single services or microservice eg: Sale microservice has dependency products microservice and order microservice. Chained microservice design pattern will help you to provide the consolidated outcome to your request. The request received by a microservice-1, which is then communicating with microservice-2 and it may be communicating with microservice-3. All these services are synchronous calls.
Branch Pattern
A microservice may need to get the data from multiple sources including other microservices. Branch microservice pattern is a mix of Aggregator & Chain design patterns and allows simultaneous request/response processing from two or more microservices. The invoked microservice can be chains of microservices. Brach pattern can also be used to invoke different chains of microservices, or a single chain, based your business needs.
Client-Side UI Composition Pattern
When services are developed by decomposing business capabilities/subdomains, the services responsible for user experience have to pull data from several microservices. In the monolithic world, there used to be only one call from the UI to a backend service to retrieve all data and refresh/submit the UI page. However, now it won’t be the same. With microservices, the UI has to be designed as a skeleton with multiple sections/regions of the screen/page. Each section will make a call to an individual backend microservice to pull the data. Frameworks like AngularJS and ReactJS help to do that easily. These screens are known as Single Page Applications (SPA). Each team develops a client-side UI component, such an AngularJS directive, that implements the region of the page/screen for their service. A UI team is responsible for implementing the page skeletons that build pages/screens by composing multiple, service-specific UI components.
Database Patterns
Defining the database architecture for microservices we need to consider below points.
  1. Services must be loosely coupled. They can be developed, deployed, and scaled independently.
  2. Business transactions may enforce invariants that span multiple services.
  3. Some business transactions need to query data that is owned by multiple services.
  4. Databases must sometimes be replicated and shared in order to scale.
  5. Different services have different data storage requirements.
Database per Service
To solve the above concerns, one database per microservice must be designed; it must be private to that service only. It should be accessed by the microservice API only. It cannot be accessed by other services directly. For example, for relational databases, we can use private-tables-per-service, schema-per-service, or database-server-per-service.
Shared Database per Service
We have talked about one database per service being ideal for microservices. It is anti-pattern for microservices. But if the application is a monolith and trying to break into microservices, denormalization is not that easy. Later phase we can move to DB per services pattern, Till that we make follow this.A shared database per service is not ideal, but that is the working solution for the above scenario. Most people consider this an anti-pattern for microservices, but for brownfield applications, this is a good start to break the application into smaller logical pieces. This should not be applied for greenfield applications.
Command Query Responsibility Segregation (CQRS)
Once we implement database-per-service, there is a requirement to query, which requires joint data from multiple services. it’s not possible. CQRS suggests splitting the application into two parts — the command side and the query side.
  • The command side handles the Create, Update, and Delete requests
  • The query side handles the query part by using the materialized views
The event sourcing pattern is generally used along with it to create events for any data change. Materialized views are kept updated by subscribing to the stream of events.
Event Sourcing
Most applications work with data, and the typical approach is for the application to maintain the current state. For example, in the traditional create, read, update, and delete (CRUD) model a typical data process is to read data from the store. It contains limitations of locking the data with often using transactions.
The Event Sourcing pattern [8] defines an approach to handling operations on data that’s driven by a sequence of events, each of which is recorded in an append-only store. Application code sends a series of events that imperatively describe each action that has occurred on the data to the event store, where they’re persisted. Each event represents a set of changes to the data (such as AddedItemToOrder).
The events are persisted in an event store that acts as the system of record. Typical uses of the events published by the event store are to maintain materialized views of entities as actions in the application change them, and for integration with external systems. For example, a system can maintain a materialized view of all customer orders that are used to populate parts of the UI. As the application adds new orders, adds or removes items on the order, and adds shipping information, the events that describe these changes can be handled and used to update the materialized view. The figure shows an overview of the pattern.
Event Sourcing pattern[8]
Saga Pattern
When each service has its own database and a business transaction spans multiple services, how do we ensure data consistency across services. Each request has a compensating request that is executed when the request fails. It can be implemented in two ways:
  • Choreography — When there is no central coordination, each service produces and listens to another service’s events and decides if an action should be taken or not. Choreography is a way of specifying how two or more parties; none of which has any control over the other parties’ processes, or perhaps any visibility of those processes — can coordinate their activities and processes to share information and value. Use choreography when coordination across domains of control/visibility is required. You can think of choreography, in a simple scenario, as like a network protocol. It dictates acceptable patterns of requests and responses between parties.
Saga pattern — Choreography
  • Orchestration — An orchestrator (object) takes responsibility for a saga’s decision making and sequencing business logic. when you have control over all the actors in a process. when they’re all in one domain of control and you can control the flow of activities. This is, of course, most often when you’re specifying a business process that will be enacted inside one organization that you have control over.
Sage pattern — Orchestration

Observability Patterns

Log Aggregation
Consider a use case where an application consists of multiple services. Requests often span multiple service instances. Each service instance generates a log file in a standardized format. We need a centralized logging service that aggregates logs from each service instance. Users can search and analyze the logs. They can configure alerts that are triggered when certain messages appear in the logs. For example, PCF does have Log aggregator, which collects logs from each component (router, controller, diego, etc…) of the PCF platform along with applications. AWS Cloud Watch also does the same.
Performance Metrics
When the service portfolio increases due to a microservice architecture, it becomes critical to keep a watch on the transactions so that patterns can be monitored and alerts sent when an issue happens.
A metrics service is required to gather statistics about individual operations. It should aggregate the metrics of an application service, which provides reporting and alerting. There are two models for aggregating metrics:
  • Push — the service pushes metrics to the metrics service e.g. NewRelic, AppDynamics
  • Pull — the metrics services pulls metrics from the service e.g. Prometheus
Distributed Tracing
In a microservice architecture, requests often span multiple services. Each service handles a request by performing one or more operations across multiple services. While in troubleshoot it is worth to have trace ID, we trace a request end-to-end.
The solution is to introduce a transaction ID. Follow approach can be used;
  • Assigns each external request a unique external request id.
  • Passes the external request id to all services.
  • Includes the external request id in all log messages.
Health Check
When microservice architecture has been implemented, there is a chance that a service might be up but not able to handle transactions. Each service needs to have an endpoint which can be used to check the health of the application, such as /health. This API should o check the status of the host, the connection to other services/infrastructure, and any specific logic.

Cross-Cutting Concern Patterns

External Configuration
A service typically calls other services and databases as well. For each environment like dev, QA, UAT, prod, the endpoint URL or some configuration properties might be different. A change in any of those properties might require a re-build and re-deploy of the service.
To avoid code modification configuration can be used. Externalize all the configuration, including endpoint URLs and credentials. The application should load them either at startup or on the fly. These can be accessed by the application on startup or can be refreshed without a server restart.
Service Discovery Pattern
When microservices come into the picture, we need to address a few issues in terms of calling services.
With container technology, IP addresses are dynamically allocated to the service instances. Every time the address changes, a consumer service can break and need manual changes.
Each service URL has to be remembered by the consumer and become tightly coupled.
A service registry needs to be created which will keep the metadata of each producer service and specification for each. A service instance should register to the registry when starting and should de-register when shutting down. There are two types of service discovery:
  • client-side : eg: Netflix Eureka
  • Server-side : eg: AWS ALB.
service discovery [9]
Circuit Breaker Pattern
A service generally calls other services to retrieve data, and there is the chance that the downstream service may be down. There are two problems with this: first, the request will keep going to the down service, exhausting network resources, and slowing performance. Second, the user experience will be bad and unpredictable.
The consumer should invoke a remote service via a proxy that behaves in a similar fashion to an electrical circuit breaker. When the number of consecutive failures crosses a threshold, the circuit breaker trips, and for the duration of a timeout period, all attempts to invoke the remote service will fail immediately. After the timeout expires the circuit breaker allows a limited number of test requests to pass through. If those requests succeed, the circuit breaker resumes normal operation. Otherwise, if there is a failure, the timeout period begins again. This pattern is suited to, prevent an application from trying to invoke a remote service or access a shared resource if this operation is highly likely to fail.
Circuit Breaker Pattern [10]
Blue-Green Deployment Pattern
With microservice architecture, one application can have many microservices. If we stop all the services then deploy an enhanced version, the downtime will be huge and can impact the business. Also, the rollback will be a nightmare. Blue-Green Deployment Pattern avoid this.
The blue-green deployment strategy can be implemented to reduce or remove downtime. It achieves this by running two identical production environments, Blue and Green. Let’s assume Green is the existing live instance and Blue is the new version of the application. At any time, only one of the environments is live, with the live environment serving all production traffic. All cloud platforms provide options for implementing a blue-green deployment.
Blue-Green Deployment Pattern

Pattern: Command Query Responsibility Segregation (CQRS)

How to implement a query that retrieves data from multiple services in a microservice architecture?

Solution

Define a view database, which is a read-only replica that is designed to support that query. The application keeps the replica up to data by subscribing to Domain events published by the service that own the data.

Microservices Design Patterns - API Gateway

Main Objective

The purpose of the API Gateway is to represent a single point of entry to all those clients, and at the same time, to abstract the complexities of communication issues such as protocol transactions and data conversions.
The picture below highlights the API Gateway pattern in microservices architecture:
Image title

Benefits

The API gateway is a protocol-agnostic solution that serves distinct clients across several communication channels. It exposes each API for each consumer, according to the communication and client types, and embraces security once it is the main entry point. It abstracts any refactoring or break-down structures on existing systems (the so-called monoliths) to its clients, and abstracts underlying microservices topology and technologies involved to final consumers.

How to Implement It

Today the most popular available implementations to realize an API gateway solution are:

SHARING LEARNING OF  MICROSERVICES ARCHITECTURE IMPLEMENTATION

  1. Find the best microservices architecture
  2. Outline your microservices
  3. Domain-Driven Design
  4. Get everyone onboard
  5. Utilize RESTful APIs
  6. Build teams for specific microservices
  7. Setup server and data storage environment
  8. Use the best DevOps toolkit
  9. Monitoring is key

#1: DETERMINE IF THE MICROSERVICES ARCHITECTURE FITS YOUR REQUIREMENTS

Amazon, Twitter, eBay, and PayPal are examples of organizations that have successfully implemented the microservices architecture design. It‘s a popular pattern, however, that doesn‘t mean it will work for you.
If you can‘t break down your web app into functions that provide value then the microservices architecture won’t make sense for you. Read “Pattern: Decompose by business capability” for more insights.

#2: DEFINE YOUR MICROSERVICES

You need to make a clear differentiation between your business functions, your services, and microservices. Without this, there is a possibility that you will build microservices that are too large. This is a form of under-fragmentation, and you will see no benefits from using the microservices approach.

#3: USE ‘DOMAIN-DRIVEN DESIGN’ (DDD) TO DESIGN MICROSERVICES

While this step is closely related to the exercise of defining your microservices, it goes one step further. Here, you design your microservices around your business domains. Let‘s review the Netflix example once more. They run their content delivery and different tracking services from separate servers.
’Domain-Driven Design‘ (DDD) is a design principle that expresses an object-oriented model using practical rules and ideas. It helps software architects to understand the differnt business domains, therefore, they can build a microservices architecture that the business can understand well. Read more about it in “DDD 101 — the 5-Minute tour”.

#4: GET EARLY BUY-IN FROM THE ORGANIZATIONAL LEADERS AND THE TEAM

Implementing the microservice architecture design isn’t simply a technical decision. Such a transformation is expensive, moreover, the impact goes beyond just the in-house development team. The transition from a monolithic architecture is a long-drawn out project. The senior management in the organization must commit the funds for it.

#5: USE RESTFUL APIS OPTIMALLY

The microservices architecture pattern can deliver a significant value if you make optimal use of RESTful APIs. RESTful APIs offer numerous advantages, for e.g., you don’t need to install anything on the client side. You don’t need SDKs or frameworks since HTTP requests to consume the API service is sufficient. Read more about the advantages of RESTful APIs in this Quora Q&A thread.

#6: PROVISION OF SEPARATE DATA STORAGE FOR EACH MICROSERVICE

Each microservice should have provision for its‘ data storage. Each microservice should fully own its’ data. Of course, data can be shared between microservices, however, this should happen via APIs.
If multiple microservices share the same data storage, this will lead to coupling between services. This will defeat the purpose of the microservices architecture considerably. Read more about it in “Top 5+ microservices architecture and design best practices”.

#7: USE A GOOD DEVOPS TOOLSET

By now, you should have designed your microservices well enough to deploy them independently. To realize optimal value from these microservices, you need to automate build and deployment management. Therefore, you will need a good set of DevOps tools.

#8: INVEST IN MONITORING

If you were using a monolithic architecture and are transitioning to a microservices architecture, you have to address increased complexity. Increased demand for performance and the dynamic environment requires more advanced monitoring.

Microservices Solution Patterns

Pattern 1: Monolithic + Service Mesh + Message Broker



Pattern 2: Monolithic  + Micro Integration + Service Mesh



Pattern 3: Service Mesh + Micro Integration + Edge Gateway



The Microservices Design Pattern



Microservice Design Patterns for Performance Monitoring

Monitoring the performance is an important aspect for a successful microservice architecture. It helps calculate the efficiency and understand any drawbacks which might be slowing the system down. Remember the following patterns related to observability for ensuring a robust microservice architecture design.

1. Log Aggregation

When we refer to a microservice architecture we are referring to a refined yet granular architecture where an application is consisting a number of microservices. These microservices run independently and simultaneously as supporting multiple services as well as their instances across various machines. Every service generates an entry in the logs regarding its execution. How can you keep a track for numerous service related logs? This is where log aggregation steps in. As a best practice to prevent from chaos, you should be having a master logging service. This master logging service should be responsible for aggregating the logs from all the microservice instances. This centralized log should be searchable, making it easier to monitor.

2. Synthetic Monitoring a.k.a Semantic Monitoring

As I explained previously, monitoring is a painful but indispensable task for a successful microservice architecture. With simultaneous execution of hundreds of services it becomes troublesome to pinpoint the root area responsible for the failure in log registry. Synthetic monitoring gives a helping hand. When you perform automated test then synthetic monitoring helps to regularly map the results in comparison to the production environment. User gets alerted if a failure is generated. Using Semantic Monitoring you can aim for 2 things using a single arrow
  • Monitoring automated test cases.
  • Detecting Production failures in terms of business requirements.

3. API Health Check

Microservice architecture design promotes services which are independent of each other to avoid any delay in the system. APIs as we know serve as the building blocks of an online connectivity. It is imperative to keep a health check on your APIs on regular basis to realize any roadblock. It is often observed that a microservice is up and running yet incapacitated for handling requests. This can be due to many factors:
  • Server Loads
  • User Adoption
  • Latency
  • Error Logging
  • Market Share
  • Downloads
In order to overcome this scenario we should ensure that every service running must have a specific health check API endpoint. For example: HTTP/health when appended at the end of every service will return the health status for respective service instance. A service registry periodically appeals to the health check API endpoint to perform a health scan. The health check would provide you with the information on the below-mentioned:
  1. A logic that is specific to your application.
  2. Status of the host.
  3. Status of the connections to other infrastructure or connection to any service instance.

Breaking it all down to Business Capability

The process of ‘decomposing’ a monolithic architecture into a microservice needs to follow certain parameters. These parameters have a different basis. Today we will look at the decomposition of the microservice design patterns which leave a lasting impact.

1. Unique Microservice for each Business Capability

A microservice is as successful as its combination of high cohesion and loose coupling. Services need to be loosely coupled while keeping the function of similar interests together. But how do we do it? How do we decompose a software system into smaller independent logical units?
We do so by defining the scope of a microservice to support a specific business capability.
For Example – 
In every organization, there are different departments that come together as one. These include technical, marketing, PR, sales, service, and maintenance. To picture a microservice structure these different domains would each be the microservices and the organization will be the system. 
So an Inventory management is responsible for all the inventories. Similarly, Shipping management will handle all the shipments and so on.
To maintain efficiency and foresee growth, the best solution is to decompose the systems using business capability. This includes classification into various business domains which are responsible to generate value in their own capabilities.

2. Microservices around similar Business Capability

Despite segregating on the basis of business capabilities, microservices often come up with a greater challenge. What about the common classes among the services? Well, decomposing these classes known as ‘God Classes’ needs intervention. For example, in case of an e-commerce system, the order will be common to several services such as order number, order management, order return, order delivery etc. To solve this issue, we turn to a common microservice design principle known as Domain-Driven Design (DDD).
In Domain-Driven Design, we use subdomains. These subdomain models have defined scope of functionality which is known as bounded context. This bounded context is the parameter used to create each microservice thus overcoming the issues of common classes.

3. Strangler Vine Pattern

While we discuss decomposition of a monolithic architecture, we often miss out the struggle of converting a monolithic system to design microservice architecture. Without hampering the working, converting can be extremely tough. And to solve this problem we have the strangler pattern, based on the vine analogy. Here is what the Strangler patterns mean in Martin Fowler’s words:
“One of the natural wonders of this area [Australia] is the huge strangler vines. They seed in the upper branches of a fig tree and gradually work their way down the tree until they root in the soil. Over many years they grow into fantastic and beautiful shapes, meanwhile strangling and killing the tree that was their host.”
Strangler pattern is extremely helpful in case of a web application where breaking down a service into different domains is possible. Since the calls go back and forth, different services live on different domains. So, these two domains exist on the same URI. Once the service has been reformed, it ‘strangles’the existing version of the application. This process is followed until the monolith doesn’t exist.

Microservice Design Patterns for Optimizing Database Storage

For a microservice architecture, loose coupling is a basic principle. This enables deployment and scalability of independent services. Multiple services might need to access data not stored in their unit. But due to loose coupling, accessing this data can be a challenge. Mainly because different services have different storage requirements and access to data is limited in microservice design. So, we look at some major database design patterns as per different requirements.

1. Individual Database per Service

Usually applied in Domain Driven Designs, one database per service articulates the entire database to a specific microservice. Due to the challenges and lack of accessibility, a single database per service needs to be designed. This data is accessible only by the microservice. This database has limited access for any outside microservices. The only way for others to access this data is through microservice API gateways.

2. Shared Database per Service

In Domain Driven Design, a separate database per service is feasible, but in an approach where you decompose a monolithic architecture to microservice, using a single database can be tough. So while the process of decomposition goes on, implementing a shared database for a limited number of service is advisable. This number should be limited to 2 or 3 services. This number should stay low to allow deployment, autonomy, and scalability.

3. Event Sourcing Design Pattern

According to Martin Fowler
Event Sourcing ensures that all changes to application state are stored as a sequence of events. Not just can we query these events, we can also use the event log to reconstruct past states, and as a foundation to automatically adjust the state to cope with retroactive changes.
The problem here lies with reliability. How can you rely on the architecture to make a change or publish a real-time event with respect to the changes in state of the application?
Event sourcing helps to come up from this situation by appending a new event to the list of the events every time a business entity changes its state. Entities like Customer may consist of numerous events. It is thus advised that an application saves a screenshot of the current state of an entity in order to optimize the load.

3. Command Query Responsibility Segregation (CQRS)

In a database-per-service model, the query cannot be implemented because of the limited access to only one database. For a query, the requirements are based on joint database systems. But how do we query then?
Based on the CQRS, to query single databases per service model, the application should be divided into two parts: Command and Query. In this model, command handles all requests related to create, update and delete while queries are taken care of through a materialized view. These views are updated through a stream of events. These events, in turn, are created using an event sourcing pattern which marks any changes in the data. These changes eventually become events.

Microservice Design Patterns for Seamless Deployment

When we implement microservices, there are certain issues which come up during the call of these services. When you design microservice architecture, certain cross-cutting patterns can simplify the working.

1. Service Discovery

The use of containers leads to dynamic allocation of the IP address. This means the address can change at any moment. This causes a service break. In addition to this, the users have to bear the load of remembering every URL for the services, which become tightly coupled.
To solve this problem and give users the location of the request, a registry needs to be used. While initiation, a service instance can register in the registry and de-register while closing. This enables the user to find out the exact location which can be queried. In addition, a health check by the registry will ensure the availability of only working instances. This also improves the system performance.

2. Blue-Green Deployment

In a microservice design pattern, there are multiple microservices. Whenever updates are to be implemented or newer versions deployed, one has to shut down all the services. This leads to a huge downtime thus affecting productivity. To avoid this issue, when you design microservice architecture, you should use the blue-green deployment pattern.
In this pattern, two identical environments run parallelly, known as blue and green. At a time only one of them is live and processing all the production traffic. For example, blue is live and addressing all the traffic. In case of new deployment, one uploads the latest version onto the green environment, switches the router to the same and thus implement the update.

Microservice Design Patterns for Performance Monitoring

Monitoring the performance is an important aspect for a successful microservice architecture. It helps calculate the efficiency and understand any drawbacks which might be slowing the system down. Remember the following patterns related to performance monitoring for ensuring a robust microservice architecture design.

1. Log Aggregation

When we refer to a microservice architecture we are referring to a refined yet granular architecture where an application is consisting a number of microservices. These microservices run independently and simultaneously as supporting multiple services as well as their instances across various machines. Every service generates an entry in the logs regarding its execution. How can you keep a track for numerous service related logs? This is where log aggregation steps in. As a best practice to prevent from chaos, you should be having a master logging service. This master logging service should be responsible for aggregating the logs from all the microservice instances. This centralized log should be searchable, making it easier to monitor.

2. Synthetic Monitoring a.k.a Semantic Monitoring

With the increase in load and microservices, it becomes important to keep a constant check on system performance. This includes any patterns which might be formed or addressing issues that come across. But more importantly, how is the data collected?
The answer lies with the use of a metric service. This metrics service is either in the Push form or the Pull form. As the name suggests, a Push service such as AppDynamics pushes the metrics to the service while a Pull service such as Prometheus pulls the data from the service.

3. Running a Health Check

Microservice architecture design promotes services which are independent of each other to avoid any delay in the system. But, there are times when the system is up and running but it fails to handle transactions due to faulty services. To avoid requests to these faulty services, a load balancing pattern has to be implemented.
To achieve this, we use ‘/health’ at the end of every service. This check is used to find out the health of the service. It includes the status of the host, its connection and the algorithmic logic.