> For the complete documentation index, see [llms.txt](https://kdongs.gitbook.io/kdocs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kdongs.gitbook.io/kdocs/microservices/microservices.md).

# Microservices

## About

A software design choice, that breaks a single application design choice (Monolith) into several pieces (Services), usually by Bounded Contexts.

Each of these services are:

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th></tr></thead><tbody><tr><td><strong>Independent from each other:</strong></td><td><ul><li><em>Will have their own databases.</em></li><li><em>Will have it's own scalability parameters.</em></li></ul><p><em><strong>You should be able to completly shutdown a microservice and this should not bring down any other microservice.</strong></em></p></td><td></td></tr><tr><td><strong>Will communicate with each other by an</strong> <code>Event Bus</code> <em><strong>(API's, Queues, Streams, etc.)</strong></em></td><td><em>Meaning that they also won't directly access other services databases.</em></td><td><strong>Will have eventual consistency</strong>, because of this async communication.</td></tr></tbody></table>

{% hint style="success" %}
One of it's major advantages is the possibility to **scale each service independently**.

Each service can be developed by it's own **separate team**, and this:

* This makes teams more autonomous.
* Accelerates development and deployment.
  {% endhint %}

{% hint style="danger" %}
Having a Microservice Architecture with:

* Scalability, Service independence, Fail tolerance and Resilience.

Requires:

* Good Strategic Modeling.
* Async communication between services.
* Event-Driven Architecture.
* CQRS.
  {% endhint %}

{% hint style="danger" %}
**Dont't have your services depend on each other.**

Having dependency between services is the worst case scenario.
{% endhint %}

<figure><img src="https://323682031-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnlFsbFv50eNWeHeOyBFh%2Fuploads%2FNj61catr4SaJv11mce2m%2Farchitecture_simple.png?alt=media&amp;token=e8f6478f-6d55-4871-bdf5-d7754d8652c3" alt=""><figcaption><p>Example</p></figcaption></figure>

### When use it

When you have to scale your teams, or the application independently.

When you have well defined contexts/business areas.

When you have maturity in deployment processes. (Like `CI/CD`)

{% hint style="warning" %}
Working with microservices will add more complexity to `versioning` and `deployment`.
{% endhint %}

## Communication Between Services

### Synchronous

When a microservice makes HTTP requests directly to another microservice to do something.

{% hint style="info" %}
Usually with `gRPC`, which will have significantly advantages over `REST`.
{% endhint %}

*Mainly used for communication for operations that require an immediate response, like data query or actions that need an immediate confirmation.*

{% hint style="danger" %}
Major downside that one service is tightly coupled to the other.
{% endhint %}

### Asynchronous

#### Over Messaging

Microservices communicate over asynchronous messages that are place over `queues` or `topics`.

*Mainly used for events and background processes, where an immediate response is not required.*

{% hint style="success" %}
Increases microservice independence.
{% endhint %}

## Choreography vs Orchestration (SAGA)

The **SAGA** pattern is commonly used to maintain consistency and resilience when multiple services must communicate with each other, or when use cases requires action from multiple services.

*e.g.: Buying a product, that will create an Order in one service, then a Payment will be created, then Inventory updates, etc.*

These services will execute in order, and failure in one of them MUST generate a **Compensatory Transactions** (which is sort of a Rollback).

{% hint style="info" %}
Since you cannot Rollback in these scenarios, because a service could have commited the data mutation to its DB, a compensation transaction must execute to **undo**.
{% endhint %}

### Choreography

A decentralized way of setting up communication between services, where each service knows what he must do next (which other services they depend on).

This way, the own service calls his Compensatory Action, and triggers the service before him.

<img src="https://323682031-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnlFsbFv50eNWeHeOyBFh%2Fuploads%2FBzFzWKDPvzL0LOxorG1g%2Ffile.excalidraw.svg?alt=media&amp;token=1a3c868d-23d5-4f98-a950-5e8c1e3b4519" alt="" class="gitbook-drawing">

#### Death Star

{% hint style="info" %}
In some extreme cases, where you have thousands of microservices you may end up with a topology like [Death Start](https://www.linkedin.com/pulse/netflix-great-devops-netfix-do-microservices-therefore-sankar-balu/).
{% endhint %}

#### Mitigate Death Star - with `Mini API Gateway`

You add `API Gateways` in front of a group of Services. *(That usually are in the same Context)*

It is also possible to add rules, like `Limits`, `Transformations`, and other resources available by an `API Gateway`.

<img src="https://323682031-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnlFsbFv50eNWeHeOyBFh%2Fuploads%2FqXnbQwbLS7dJyEdyZ0hz%2Ffile.excalidraw.svg?alt=media&amp;token=9004c48b-8e00-4bb4-a9f6-20e562683acb" alt="" class="gitbook-drawing">

### Orchestration

It is a centralized way of setting up communication between services, where a `Mediator/Orquestrator` is used to handle which service should be called after another.

And if something goes bad between a transaction, the `Mediator` can undo all in the correct order.

{% hint style="warning" %}
`Mediator` can become Single Points of Failure in the architecture.

To deal with this, the `Mediator` can be **stateless** (saving each step in a DB), or with [Patterns](/kdocs/microservices/patterns.md#transactional-outbox).
{% endhint %}

<img src="https://323682031-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnlFsbFv50eNWeHeOyBFh%2Fuploads%2FL6oQ1GPiknwsRvY03ddW%2Ffile.excalidraw.svg?alt=media&amp;token=d0a54749-7d46-4108-815d-96cc70c548d1" alt="" class="gitbook-drawing">

## Resilience

At some point every system will fail, so how can I mitigate these risks of data and transactions loss.

A system in a distributed architecture should adopt auto-preservation mechanisms to garantee its operation.

Also a system should not be selfish in doing non-stop requests to another failing system.

### Indepotence & Fallback policies

Indepotence is the ability to detect and deal with duplicity. *(Ex.: Duplicated requests sent to Queues)*

{% hint style="danger" %}
Communication between services **MUST** be idempotent.
{% endhint %}

Fallback policies to define what should happen or what should be done when something is unavailable.

### Observability

Help alot with APM (Application Performance Monitoring).

Allows easy tracing of errors with **Distributed Tracing**.

Personalized metrics.

### Healthcheck

A mechanim to check the health of systems.

An unhealth system have a chance to recover, if traffic can be redirected out of it.

{% hint style="info" %}
A good healthcheck also tests the system's dependencies.
{% endhint %}

#### Active healthcheck

In active mode, the system itself will self ping and check its health.

#### Passive healthcheck

In passive mode, the system will only know its health after someone else checked for him.

### Rate Limiting

Can protect a sytem based on the limits it was supposed/build to handle.

### Circuit Breaker

It protects a system, making all requests to it to be blocked.

<table data-view="cards"><thead><tr><th></th><th></th><th></th></tr></thead><tbody><tr><td><strong>Closed Circuit</strong></td><td>Requests arrive normally.</td><td></td></tr><tr><td><strong>Opened Circuit</strong></td><td>Requests are blocked.</td><td></td></tr><tr><td><strong>Semi Opened Circuit</strong></td><td>Allows limited amount of requests, for system check reasons.</td><td></td></tr></tbody></table>

### Retries

Policies for retrying to reach services if they fail.

#### Linear - No Backoff

Retries are done within a contant time between tries.

#### Exponential Backoff

The time between tries increase exponentialy.

#### Exponential Backoff with Jitter

Again the time between tries grows, but an additional mount of time (Jitter/Noise) is added.

{% hint style="warning" %}
Choose this policy, since it decreases the probability of different requests, retry at the same time.
{% endhint %}

### API Gateway

It is a single point of entry for a group of services.

It can garantee that inappropriate requests don't hit internal services. *(Like unauthenticated users)*

{% hint style="info" %}
`Healthcheck`, `Rate Limiting`,  `Auth`, and etc, can be implemented by API Gateway.
{% endhint %}

It also help us to organize our microservices in contexts.

API Gateways can be **stateless** or **stateful**.

<img src="https://323682031-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnlFsbFv50eNWeHeOyBFh%2Fuploads%2Fl5rnvoEo5yb32S3lW8Zc%2Ffile.excalidraw.svg?alt=media&amp;token=78227905-1de2-4743-ac22-64e14d550cc6" alt="" class="gitbook-drawing">

{% hint style="info" %}
*Ex. of API Gateways:*

`Kong`
{% endhint %}

### Service Mesh

It can control and monitor the entire network, by using `Proxies` in front of the services.

The Service Mesh handles, `Rate limiting`, `Healthchecks`, `Circuit Breakers`, `Retries`, etc..
