Microservices with event sourcing

92 Pages • 2,105 Words • PDF • 15.4 MB
Uploaded at 2021-09-24 18:21

This document was submitted by our user and they confirm that they have the consent to share it. Assuming that you are writer or own the copyright of this document, report to us by using this DMCA report button.


Developing event-driven microservices with event sourcing and CQRS Chris Richardson Author of POJOs in Action Founder of the original CloudFoundry.com @crichardson [email protected] http://plainoldobjects.com http://microservices.io @crichardson

Presentation goal

Show how Event Sourcing and Command Query Responsibility Segregation (CQRS) are a great way to implement microservices

@crichardson

About Chris

@crichardson

About Chris

Consultant and trainer focusing on microservices (http://www.chrisrichardson.net/)

@crichardson

About Chris Founder of a startup that is creating a platform that makes it easy for application developers write microservices (http://bit.ly/trialeventuate)

@crichardson

For more information https://github.com/cer/event-sourcing-examples http://microservices.io http://plainoldobjects.com/ https://twitter.com/crichardson http://eventuate.io/

@crichardson

Agenda Why event sourcing? Overview of event sourcing ACID-free design Designing a domain model based on event sourcing Implementing queries in an event sourced application Event sourcing and microservices

@crichardson

Traditional monolithic architecture WAR/EAR Spring MVC

ACID

StoreFront UI HTML

Browser/ Client

REST/JSON

Load balancer

Simple to develop test deploy scale

Shopping cart Customers

Spring Hibernate

RDBMS

Orders



Tomcat

@crichardson

But that leads to monolithic hell *

For large and/or complex applications…

@crichardson

Today: use a microservice, polyglot architecture Shopping UI

Standalone services

Orders Service

Customer Service

Order Database

Customer Database

NoSQL DB

Sharded SQL

@crichardson

But now we have distributed data management problems

@crichardson

Example: placing an order Order Service

Order Database Order #1

Customer Service NoSQL

SQL Customer Database Customer #1

No ACID

No 2PC @crichardson

How to maintain invariants? Order Service placeOrder()

Order management Order total

?

belongs to

Customer Service updateCreditLimit()

Customer management Customer

has orders

creditLimit ...

Invariant: sum(open order.total) 343}

id id :: 4567 4567 total: total: 343 343 state state == CREATED OPEN

Subscribes to:

CreditReservedEvent

publishes:

OrderCreatedEvent

Subscribes to:

OrderCreatedEvent

Message Bus

Publishes:

CreditReservedEvent

@crichardson

Now there are two problems to solve….

@crichardson

Problem #1: How to design eventually consistent business logic? More on that later…. @crichardson

Problem #2: How atomicity update database and publish an event insert Order Order Service

Order Database

?

publish OrderCreatedEvent

dual write problem

Message Broker

@crichardson

Update and publish using 2PC Guaranteed atomicity BUT Need a distributed transaction manager Database and message broker must support 2PC Impacts reliability Not fashionable 2PC is best avoided

@crichardson

Transaction log tailing How: Read the database “transaction log” = single source of truth Publish events to message broker LinkedIn databus https://github.com/linkedin/databus Supports Oracle and MySQL Publish as events AWS DynamoDB streams Ordered sequence of creates, updates, deletes made to a DynamoDB table Last 24 hours Subscribe to get changes MongoDB Read the oplog

@crichardson

Transaction log tailing: benefits and drawbacks Benefits

Drawbacks

No 2PC

Immature

No application changes required

Database specific solutions

Guaranteed to be accurate

Low-level DB changes rather business level events = need to reverse engineer domain events

Use database triggers

Track changes to tables Insert events into an event table Use datastore as a message queue Pull events from event table and write to message broker

@crichardson

Database triggers: benefits and drawbacks Benefits No 2PC No application changes required


Drawbacks Requires the database to support them Database specific solutions Low-level DB changes rather business level events = need to reverse engineer domain events Error-prone, e.g. missing trigger

Application created events Use datastore as a message queue Txn #1: Update database: new entity state & event Txn #2: Consume event Txn #3: Mark event as consumed Eventually consistent mechanism (used by eBay) See BASE: An Acid Alternative, http://bit.ly/ebaybase

@crichardson

Application created events Benefits High-level domain events No 2PC

Drawbacks Requires changes to the application Only works for SQL and some NoSQL databases Error-prone

Agenda Why event sourcing? Overview of event sourcing ACID-free design Designing a domain model based on event sourcing Implementing queries in an event sourced application Event sourcing and microservices

@crichardson

Just publish events

X

update Application

publish

Database

Message Broker

@crichardson

Event sourcing For each aggregate (business entity): Identify (state-changing) domain events Define Event classes For example, ShoppingCart: ItemAddedEvent, ItemRemovedEvent, OrderPlacedEvent Order: OrderCreated, OrderCancelled, OrderApproved, OrderRejected, OrderShipped @crichardson

Persists events NOT current state

101 Order status ….

X

Order table

ACCEPTED

Event table

101 901 OrderCreated



101 902 OrderApproved



101 903 OrderShipped

… @crichardson

Replay events to recreate state Events OrderCreated(…) OrderAccepted(…) OrderShipped(…)

Order state

Periodically snapshot to avoid loading all events @crichardson

The present is a fold over history currentState = foldl(applyEvent, initialState, events)

@crichardson

Aggregates: Command Events

Command

Aggregate

Event Event

@crichardson

Aggregates: Event

Updated

aggregate

Event

Aggregate

Aggregate’

@crichardson

Request handling in an event-sourced application Microservice A

pastEvents = findEvents(entityId)

new()

applyEvents(pastEvents)

HTTP Handler

Order newEvents = processCmd(SomeCmd)

saveEvents(newEvents)

Event Store

(optimistic locking)

@crichardson

Event Store publishes events consumed by other services Microservice B update()

subscribe(EventTypes)

Aggregate publish(event)

Event Store

Event Subscriber

update()

CQRS View

publish(event) send notifications

… @crichardson

Event store = database + message broker Save aggregate events

Get aggregate events

Hybrid database and message broker Implementations:

Event Store

Subscribe to events

Home-grown/DIY geteventstore.com by Greg Young http://eventuate.io (mine)

Benefits of event sourcing Solves data consistency issues in a Microservice/NoSQL-based architecture Reliable event publishing: publishes events needed by predictive analytics etc, user notifications,… Eliminates O/R mapping problem (mostly) Reifies state changes: Built-in, reliable audit log, temporal queries Preserved history

More easily implement future requirements

@crichardson

Drawbacks of event sourcing Weird and unfamiliar Events = a historical record of your bad design decisions Handling duplicate events can be tricky

Application must handle eventually consistent data Event store only directly supports PK-based lookup => use Command Query Responsibility Segregation (CQRS) to handle queries

@crichardson

Agenda Why event sourcing? Overview of event sourcing ACID-free design Designing a domain model based on event sourcing Implementing queries in an event sourced application Event sourcing and microservices

@crichardson

Implementing createOrder() POST /orders class OrderServiceImpl { public Order createOrder() { … Creates Order … } }

@crichardson

Implement requirements and preserve invariants Story As a customer I want to place an order So that I get the needed products

Invariant: sum(open order.total)
Microservices with event sourcing

Related documents

92 Pages • 2,105 Words • PDF • 15.4 MB

517 Pages • 185,385 Words • PDF • 10.4 MB

347 Pages • 106,578 Words • PDF • 1.3 MB

23 Pages • 17,180 Words • PDF • 1.1 MB

245 Pages • 27,398 Words • PDF • 33.7 MB

34 Pages • 11,351 Words • PDF • 204.5 KB

7 Pages • 850 Words • PDF • 855.7 KB

341 Pages • 91,516 Words • PDF • 20.6 MB

128 Pages • 29,901 Words • PDF • 1.5 MB

175 Pages • 66,054 Words • PDF • 2.4 MB

13 Pages • 2,356 Words • PDF • 1.7 MB

454 Pages • 86,211 Words • PDF • 1.7 MB