Microservice
Fleeting- External reference: https://microservices.io/patterns/data/transaction-log-tailing.html
- External reference: https://microservices.io/patterns/data/transactional-outbox.html
- External reference: https://microservices.io/patterns/data/aggregate.html
- External reference: https://microservices.io/patterns/data/domain-event.html
- External reference: https://microservices.io/patterns/data/event-sourcing.html
- External reference: https://microservices.io/patterns/data/cqrs.html
- External reference: https://microservices.io/patterns/server-side-discovery.html
- External reference: https://microservices.io/patterns/service-registry.html
- External reference: https://microservices.io/patterns/microservice-chassis.html
- External reference: https://microservices.io/patterns/client-side-discovery.html
- External reference: https://microservices.io/patterns/data/database-per-service.html
- External reference: https://microservices.io/patterns/microservices.html
- see,
- saga,
Tail the database transaction log and publish each message/event inserted into the outbox to the message broker
— https://microservices.io/patterns/data/transaction-log-tailing.html
Relatively obscure although becoming increasing common
— https://microservices.io/patterns/data/transaction-log-tailing.html
Tricky to avoid duplicate publishing
— https://microservices.io/patterns/data/transaction-log-tailing.html
How to reliably/atomically update the database and publish messages/events?
— https://microservices.io/patterns/data/transactional-outbox.html
service that uses a relational database inserts messages/events into an outbox table
— https://microservices.io/patterns/data/transactional-outbox.html
service that uses a NoSQL database appends the messages/events to attribute of the record
— https://microservices.io/patterns/data/transactional-outbox.html
The service publishes high-level domain events
— https://microservices.io/patterns/data/transactional-outbox.html
No 2PC required
— https://microservices.io/patterns/data/transactional-outbox.html
The Event sourcing is an alternative solution
— https://microservices.io/patterns/data/transactional-outbox.html
From Domain-Driven Design (DDD).
A graph of objects that can be treated as a unit
Organize the business logic of a service as a collection of DDD aggregates that emit domain events when they created or updated. The service publishes these domain events so that they can be consumed by other services
Event sourcing persists the state of a business entity such an Order or a Customer as a sequence of state-changing events. Whenever the state of a business entity changes, a new event is appended to the list of events. Since saving an event is a single operation, it is inherently atomic. The application reconstructs an entity’s current state by replaying the events
— https://microservices.io/patterns/data/event-sourcing.html
Applications persist events in an event store, which is a database of events.
— https://microservices.io/patterns/data/event-sourcing.html
The store has an API for adding and retrieving an entity’s events. The event store also behaves like a message broker. It provides an API that enables services to subscribe to events. When a service saves an event in the event store, it is delivered to all interested subscribers
— https://microservices.io/patterns/data/event-sourcing.html
order to optimize loading, an application can periodically save a snapshot of an entity’s current state. To reconstruct the current state, the application finds the most recent snapshot and the events that have occurred since that snapshot. As a result, there are fewer events to replay
— https://microservices.io/patterns/data/event-sourcing.html
solves one of the key problems in implementing an event-driven architecture and makes it possible to reliably publish events whenever state changes
— https://microservices.io/patterns/data/event-sourcing.html
Because it persists events rather than domain objects, it mostly avoids the object‑relational impedance mismatch problem
— https://microservices.io/patterns/data/event-sourcing.html
100% reliable audit log of the changes made to a business entity
— https://microservices.io/patterns/data/event-sourcing.html
different and unfamiliar style of programming and so there is a learning curve.
— https://microservices.io/patterns/data/event-sourcing.html
difficult to query since it requires typical queries to reconstruct the state of the business entities. That is likely to be complex and inefficient
— https://microservices.io/patterns/data/event-sourcing.html
As a result, the application must use Command Query Responsibility Segregation (CQRS) to implement queries. This in turn means that applications must handle eventually consistent data
— https://microservices.io/patterns/data/event-sourcing.html
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.
Supports multiple denormalized views that are scalable and performant
Improved separation of concerns = simpler command and query models
Increased complexity
- Potential code duplication
- Replication lag/eventually consistent views
When making a request to a service, the client makes a request via a router (a.k.a load balancer) that runs at a well known location. The router queries a service registry, which might be built into the router, and forwards the request to an available service instance.
— https://microservices.io/patterns/server-side-discovery.html
Implement a service registry, which is a database of services, their instances and their locations. Service instances are registered with the service registry on startup and deregistered on shutdown. Client of the service and/or routers query the service registry to find the available instances of a service. A service registry might invoke a service instance’s health check API to verify that it is able to handle requests
Build your microservices using a microservice chassis framework, which handles cross-cutting concerns
— https://microservices.io/patterns/microservice-chassis.html
The major benefit of a microservice chassis is that you can quickly and easy get started with developing a microservice
— https://microservices.io/patterns/microservice-chassis.html
When making a request to a service, the client obtains the location of a service instance by querying a Service Registry, which knows the locations of all service instances
— https://microservices.io/patterns/client-side-discovery.html
Keep each microservice’s persistent data private to that service and accessible only via its API. A service’s transactions only involve its database
— https://microservices.io/patterns/data/database-per-service.html
service’s database is effectively part of the implementation of that service. It cannot be accessed directly by other services
— https://microservices.io/patterns/data/database-per-service.html
Without some kind of barrier to enforce encapsulation, developers will always be tempted to bypass a service’s API and access it’s data directly.
— https://microservices.io/patterns/data/database-per-service.html
Distributed transactions are best avoided because of the CAP theorem. Moreover, many modern (NoSQL) databases don’t support them.
— https://microservices.io/patterns/data/database-per-service.html
There are various patterns/solutions for implementing transactions and queries that span services:
— https://microservices.io/patterns/data/database-per-service.html
There are logical components corresponding to different functional areas of the application
team of developers
New team members must quickly become productive
each service is relatively small and so is easier to understand and change
additional complexity
inter-service communication mechanism and deal with partial failure
Implementing requests that span multiple services is more difficult
tangled dependencies might make it difficult to decompose your monolithic application into a set of services.
SRP defines a responsibility of a class as a reason to change, and states that a class should only have one reason to change. It make sense to apply the SRP to service design as well.
loose coupling, each service has its own database.
application must instead use the Saga pattern
service publishes an event when its data changes. Other services consume that event and update their data. There are several ways of reliably updating data and publishing events including Event Sourcing and Transaction Log Tailing
The Database per Service pattern describes how each service has its own database in order to ensure loose coupling
The API Gateway pattern defines how clients access the services in a microservice architecture