Stateless Design
Context
Microservices are being adopted. There is a microservice in place that makes use of states (e.g. caching, sessions, etc.)
Problem
- Scaling the microservices by simple replication leads to inconsistencies between instances since the state is not shared.
- At failure, the state of the microservice instance is lost and cannot be recovered leading to inconsistencies with clients.
- Sharing state lead to cascading failures between the instances of the microservices since the shared state can be polluted.
Solution
Design the microservices in a stateless way to avoid sharing state between its instances.
Being stateless means not saving a state in-memory, nor on a local storage like on disk since both are ephemeral in a containerized environment. Sessions with communication partners should be avoided as they implicate maintaining a state.
If the microservice has to manage the data it is responsible for, this data is maintained in a microservice-specific database that is shared between the microservice instances. In other words, the "state" is pushed to the database level or to some other external component.
In some cases, the state can also be pushed to the consumer, meaning that client requests have to contain the context information in order fulfill the request.
Not relying on a state will make the microservice instances interchangeable for interactions. This simplifies load balancing between instances and improves the fault tolerance of the microservice. Not sharing state means that instances cannot influence each other and prevents error cascading by a polluted state (except the one written to the database).
Maturity
Proposed, requires evaluation.
Sources of Evidence
L5:
- 12-factor and cloud native designs demand statelessness as best practice for microservices
L9:
- State either on disk or in memory
- Fault tolerance and scaling => mechanism to allow replication of application state
- If Stateful: complex
- Containers don't allow yet sharing memory =>
- (1) use disk to store state: shared storage, disk colume migration, application-level data replication
- (2) rely on clients to tolerate loss or inconsistency of state of failed services
- Containers don't allow yet sharing memory =>
- Statelessness has clear benefits (in OpenStack), easier
L14:
- Microservices at Otto.de; more Self-contained systems
- "Shared nothing" principle: no shared state, no infrastructure components besides the two proxies, no database, or other shared resources.
- No HTTP sessions, shared caches
- Only limited amount of client-side state (cookies, local storage) as sharing between systems => esp. for auth
- (+) excellent horizontal scalability
- (+) improved fault tolerance: not sharing => no impact on each other
L17:
- Stateless architecture is common for microservices
L22:
- Standards for services, usually stateless, message-oriented, and hypermedia-driven
L25:
- statelessness => easy restarting service => failure safety
L46:
- same as SOA: stateless services
L61:
- pushing as much as possible towards stateless microservices as means of fault tolerance
LN42:
- challenges and disadvantages of microservices
- among others: state management
- migration poses challenges regarding statefulness (among others)
LN44:
- situation-dependent attributes of microservices
- self-contained, coarse-grained, visible/discoverable, stateless, idempotent, reusable, composable, vendor-diverse
Interview A:
- did 12-Factor App, cloud native => includes stateless
- statelessness => each service have own database