Top Banner
@crichardson E vent-driven microservices with event sourcing and CQRS Chris Richardson Founder of Eventuate.io Founder of the original CloudFoundry.com Author of POJOs in Action @crichardson [email protected] http://eventuate.io July 2016
62

Developing event-driven microservices with event sourcing and CQRS (Shanghai)

Apr 16, 2017

Download

Software

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Event-driven microservices with event sourcing and CQRS

Chris Richardson

Founder of Eventuate.io Founder of the original CloudFoundry.com Author of POJOs in Action

@crichardson [email protected] http://eventuate.io July 2016

Page 2: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Presentation goal

Show how Event Sourcing and Command Query Responsibility

Segregation (CQRS) are a great way to implement

microservices

Page 3: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

About Chris

Page 4: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

About Chris

Consultant and trainer focusing on modern

application architectures including microservices

(http://www.chrisrichardson.net/)

Page 5: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

About Chris

Founder of a startup that is creating a platform that makes it easier for developers to write transactional

microservices (http://eventuate.io)

Page 6: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

For more information

http://learnmicroservices.io

Page 7: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Agenda

Monolith vs. microservices

Event-driven microservices

Overview of event sourcing

Implementing queries in an event sourced application

Page 8: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Let’s imagine you are building a large, complex application,

e.g. an online store

Page 9: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Successful software development

Architecture

Process OrganizationAgile Continuous delivery …

Small, autonomous, teams

Page 10: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

?Architecture

Page 11: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Page 12: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

The monolithic architecture

Tomcat

Browser

WAR

SQL database

HTML

REST/JSON

Client App

Simple to ….

Develop Test

Deploy Scale

Catalog Module

Reviews Module

Orders Module

StoreFront UI Module

Page 13: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

But successful

applications keep

growing ….

Page 14: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Monolithic architecture

Process OrganizationAgile Continuous delivery …

Small, autonomous, teams

Page 15: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Apply functional decomposition

X axis - horizontal duplication

Z axis

- data

partit

ioning

Y axis - functional

decomposition

Scale b

y split

ting s

imilar

thing

s

Scale by splitting

different things

Page 16: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Microservice architecture

Browser

Mobile Device

Store Front UI

API Gateway

Catalog Service

Review Service

Order Service

… Service

Catalog Database

Review Database

Order Database

… Database

HTML

REST

REST

REST

Page 17: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Microservice architecture

Process OrganizationAgile Continuous delivery …

Small, autonomous, teams✔ ✔

Page 18: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Drawbacks

Complexity

Page 19: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

DrawbacksComplexity of developing a distributed system

Implementing inter-process communication

Handling partial failures

Complexity of implementing business transactions that span multiple databases (without 2PC)

Complexity of testing a distributed system

Complexity of deploying and operating a distributed system

Managing the development and deployment of features that span multiple services

Fortunately solutions exists

Page 20: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

The benefits typically outweigh the drawbacks

for large, complex applications

Page 21: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Issues to address

How to deploy the services?

How do the services communicate?

How do clients of the application communicate with the services?

How to partition the system into services?

How to deal with distributed data management problems?

….

Page 22: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Microservices pattern language

http://microservices.io/

Page 23: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Agenda

Monolith vs. microservices

Event-driven microservices

Overview of event sourcing

Implementing queries in an event sourced application

Page 24: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

Data management patterns

Page 25: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

The Database

Shared database

Order Service Customer Service … Service

Order table Customer table …

orderTotal creditLimit

Tight coupling Simple and

ACID

Page 26: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Database per service

Order Service Customer Service

Order Database Customer Database

Order table Customer table

orderTotal creditLimit

Loose coupling 😀 but more complex 😓 and….

Page 27: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

2PC (aka. distributed transactions)

is not viable choice for most modern applications

Page 28: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Customer management

How to maintain data consistency without 2PC?

Order management

Order Service

placeOrder()

Customer Service

updateCreditLimit()

Customer

creditLimit ...

has ordersbelongs toOrder

total

Invariant: sum(open order.total) <= customer.creditLimit

?

Page 29: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Event-driven architecture

Page 30: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Use event-driven, eventually consistent order processing

Order Service

Customer Service

Order created

Credit Reserved

Credit Check Failed

Place Order

OR

Page 31: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

How atomically update database and publish an event

Order Service

Order Database

Message Broker

insert Order

publish OrderCreatedEvent

dual write problem

?

Page 32: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Failure = inconsistent system

Order Service

Order Database

Message Broker

insert Order

publish OrderCreatedEvent

X

Page 33: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

2PC is not an option

Page 34: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Reliably publish events when state changes

Page 35: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Agenda

Monolith vs. microservices

Event-driven microservices

Overview of event sourcing

Implementing queries in an event sourced application

Page 36: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Just publish events

Application

Database

Message Broker

update

publish

X

Page 37: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Event sourcingFor each domain object (i.e. DDD aggregate):

Identify (state changing) domain events, e.g. use Event Storming

Define Event classes

For example,

ShoppingCart: ItemAddedEvent, ItemRemovedEvent, OrderPlacedEvent

Order: OrderCreated, OrderCancelled, OrderApproved, OrderRejected, OrderShipped

Page 38: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Persists events NOT current state

Order

status ….

101 ACCEPTED

Order tableX

Page 39: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Persists events NOT current state

Event table

Entity type Event id

Entity id

Event data

Order 902101 …OrderApproved

Order 903101 …OrderShipped

Event type

Order 901101 …OrderCreated

Page 40: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Replay events to recreate state

Order

state

OrderCreated(…) OrderAccepted(…) OrderShipped(…)

Events

Periodically snapshot to avoid loading all events

Page 41: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

The present is a fold over history

currentState = foldl(applyEvent, initialState, events)

Page 42: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Familiar concepts restructured

class Customer {

public void reserveCredit( orderId : String, amount : Money) {

// verify

// update state this.xyz = … }

public List<Event> process( ReserveCreditCommand cmd) { // verify … return singletonList( new CreditReservedEvent(…); ) }

public void apply( CreditReservedEvent event) { // update state this.xyz = event.xyz }

Page 43: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Event

Aggregates: Command ⇒ Events

AggregateCommand Event

Page 44: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Aggregates: Event ⇒ Updated aggregate

AggregateEvent Updated Aggregate

Page 45: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Request handling in an event sourced application

HTTP Handler

Event Store

pastEvents = findEvents(entityId)

Order

new()

applyEvents(pastEvents)

newEvents = processCmd(someCmd)

saveEvents(newEvents) (optimistic locking)

Order Service

applyEvents(newEvents)

Page 46: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Event Store publishes events consumed by other services

Event Store

Event Subscriber

subscribe(EventTypes)

publish(event)

publish(event)

Customer

update()

Customer Service

Page 47: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Event Store publishes events consumed by other services

Event Store

Event Subscriber

subscribe(EventTypes)

publish(event)

publish(event)

CQRS View

update()

Service Xyz

send notifications

Page 48: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

Event store = database + message broker

Hybrid database and message broker

Implementations:

Home grown/DIY

geteventstore.com by Greg Young

http://eventuate.io (mine)

Event Store

Save aggregate

events

Get aggregate

events

Subscribe to events

Page 49: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Benefits of event sourcingSolves 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

Page 50: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Drawbacks of event sourcingRequires application rewrite

Weird and unfamiliar style of programming

Events = a historical record of your bad design decisions

Must detect and ignore duplicate events

Idempotent event handlers

Track most recent event and ignore older ones

Querying the event store can be challenging

Some queries might be complex/inefficient, e.g. accounts with a balance > X

Event store might only support lookup of events by entity id

Must use Command Query Responsibility Segregation (CQRS) to handle queries ⇒ application must handle eventually consistent data

Page 51: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Agenda

Monolith vs. microservices

Event-driven microservices

Overview of event sourcing

Implementing queries in an event sourced application

Page 52: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Find recent, valuable customers

SELECT * FROM CUSTOMER c, ORDER o WHERE c.id = o.ID AND o.ORDER_TOTAL > 100000 AND o.STATE = 'SHIPPED' AND c.CREATION_DATE > ?

Customer Service

Order Service

What if event sourcing is

used?…. is no longer easy

Page 53: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Use Command Query Responsibility Segregation

(CQRS)

Page 54: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Command Query Responsibility Segregation (CQRS)

Application logic

Commands Queries

X

Page 55: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Command Query Responsibility Segregation (CQRS)

Command side

Commands

Aggregate

Event Store

Events

Query side

Queries

(Materialized) View

Events

Page 56: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Query side design

Event Store

Updater

View Updater Service

Events

Reader

HTTP GET Request

View Query Service

View Store

e.g. MongoDB

ElasticSearch Neo4J

update query

Page 57: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Persisting a customer and order history in MongoDB

{ "_id" : "0000014f9a45004b 0a00270000000000", "_class" : "net.chrisrichardson…..views.orderhistory.CustomerView", "version" : NumberLong(5), "orders" : { "0000014f9a450063 0a00270000000000" : { "state" : "APPROVED", "orderId" : "0000014f9a450063 0a00270000000000", "orderTotal" : { "amount" : "1234" } }, "0000014f9a450063 0a00270000000001" : { "state" : "REJECTED", "orderId" : "0000014f9a450063 0a00270000000001", "orderTotal" : { "amount" : "3000" } } }, "name" : "Fred", "creditLimit" : { "amount" : "2000" } }

Denormalized = efficient lookup

Page 58: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Persisting customers and order info using Spring Data for MongoDB...

Page 59: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Persisting customers and order using Spring Data for MongoDB...

Page 60: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

Benefits and drawbacks of CQRS

Benefits

Necessary in an event sourced architecture

Separation of concerns = simpler command and query models

Supports multiple denormalized views

Improved scalability and performance

Drawbacks

Complexity

Potential code duplication

Replication lag/eventually consistent views

Page 61: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

Summary

Use microservices to accelerate development

Use an event-driven architecture to maintain data consistency

Implement an event-driven architecture using event sourcing

Use CQRS to implement materialized views for queries

Page 62: Developing event-driven microservices with event sourcing and CQRS (Shanghai)

@crichardson

@crichardson [email protected]

http://learnmicroservices.io

Questions?