These are my notes for the 2-day training about microservice architectures given by Sam Newman. It consisted on a selection of patterns to build a microservice based system and some others to migrate from a monolithic application. The list of patterns include their pro/cons, domain of applicability and technologies that implement them.

Definition of microservice architecture

The microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery.

My feeling about the training

The trainer had excellent presentation skills and a broad knowledge derived from extensive consulting experience. Although roughly 40% of the content was obvious, 60% did provide some valid insights. It was mostly a lecture listing patterns, no hands-on training. It would have been nice to have some working code to bring back home …

Why microservices ?

Theoritically microservices architectures enable :

On the other side you will struggle with :

The layer architecture (UI, business logic, persistence) favors competence based teams (middleware, db..). This introduces change friction because each minor change has to be coordinated amongst several teams. Some studies suggest a strong correlation between shared ownership and defects.

Domain driven design (DDD)

When designing services you struggle between :

Domain driven design is a method to split the system into micro services. Because business domains change less often than the technology stack => interface stability.

Domain models should be confined to an explicit scope. It is not cost effective to define a model to the company scale. Bounded contexts follow this idea by controlling the semantics of a given object across different parts of the organisation. Example customer model : On a retail site, a customer has different attributes for search, delivery, payment services. If you build a service to handle all possible attributes of customer then you introduce coupling between search, delivery, payment services.

DDD methodology : Event storming

The event storming method is decomposes a system into bounded contexts. Some guidelines :

Monolith migration

The most important metric is the number of services on your system. It correlates to the investement needed in infrastructure to ease the pain of managing lots of independent services. An interesting example is gilt. By plotting the number of deployed services vs headcount, you notice it took several years for this company to reduce the cost of adding new sevices.

Table wrapper anti-pattern : one way to decouple a piece of the database is to create that acts as a proxy to the table. However the coupling introduced by the data schema is not solved by this pattern. The service proxying the database should expose methods to transition the data between valid states.

How to identify code to migrate ?

You need to balance the ease of migration with the rate of change of the sub-system. There is no profit (other than experience) in migrating a sub-system that never changes. These tools can provide some insights into code dependency, tech debt and even social metrics !

Patterns for monolith migration

Monoliths for greenfields

At the end of the day unless you have the right automation and experience, the monolith is always the fatest and cheaper way to start building value for your organisation. Many fancy companies started like that (etsy).

Better have a monolith with strong boundaries in terms of code packaging and database schemas that can be evolved later.

Service discovery

How do you enable communication between servers ? Communication entails more than just knowing the endpoint and sending JSON/HTTP.

You may distribute client libraries for each service, but it starts to get complicated on a polyglot environment.

Service mesh (or side car pattern)

Service mesh is middleware to provide the advanced service discovery features above. Recommended implementations : linkerd, istio.

Choreography Vs Orchestration

Collaboration styles are related to messaging patterns

Orchestration Choreogaphy
self documenting business logic code does not provide a complete picture of the business process
centralized error management how can we even know the process actually finished ?
orchestrator has to know about all subcomponents, it will be involved in most of the changes the only coupling between subcomponents is the event to listen to
no need for middleware message broker/queue needed to distribute (persist?) the events

The biggest shortcoming of the choreography collaboration is that you will always need an orchestrator to check all subcomponents finished correctly. You need to limit the coupling introduced by this reconciliation orchestrator by only listening to the end events pushed by each subcomponent.

To avoid shared state we can use the data on the outside pattern.

Retry policy

On monoliths, most of the calls are local so the failure behaviour is binary, either it works or not. On the contrary calls crossing microservices boundaries may have transient failures. However the answer is not always to retry, on a complex call flow this with nested retry attempts can produce very high latency.

Slow failure

This is on of the worst types of failures because it can block all of its callers. Indeed, if threads are used by the callers to make service calls, a slow responding (or timing out) service will hog all resources.

If possible you can spool retry operations to be dequeued later or put a queue in the middle so that clients can enqueue and return independently of whether the service is online.

Tracing, performance/business KPI, monitoring, alerting

To track complex call graphs you need to include a correlation id on each message. You cannot always delegate this to your service mesh for asynchronous communication. To avoid pain all log records should be consistent independently of the language used. Include in your set of KPIs both technical and business metrics.

Do not only build alerts for errors. Define a model to define normal operation and use alerting to warn you when the system is not working normally. Example : a KPI to indicate normal behavior may be the revenue generated per hour.

Some useful tools :

Security

Microservices are a double edged sword when it comes to security.

Attack trees : a methodology for threat modelling

Confused deputy attack

You need to enforce permissions based on both user and service. Otherwise a service that is permissioned to access sensitive information may be used by an attacker. If the attacker can request data for other users without a strong authentication proof, the data is not secure.

Random bits of interesting stuff