Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
@crichardson
Not Just Events: Developing
Asynchronous Microservices 
Chris Richardson
Founder of Eventuate.io
Founder of t...
@crichardson
Presentation goal
Using asynchronous
messaging to implement
transactions and queries in a
microservice archit...
@crichardson
Presentation goal
Microservices != REST
Microservices != Events
Microservices != Event Sourcing
Apache Kafka ...
@crichardson
About Chris
@crichardson
About Chris
Consultant and trainer
focussed on helping
organizations adopt the
microservice architecture
(htt...
@crichardson
About Chris
Founder of a startup that is creating
an open-source/SaaS platform
that simplifies the development...
@crichardson
About Chris
https://www.manning.com/books/microservices-patterns
40% discount with code
ctwmucon18
About Chris: microservices.io
Microservices pattern
language
Articles
Code examples
Microservices Assessment
Platform - co...
@crichardson
Agenda
Transactions, queries and microservices
Managing transactions with sagas
Implementing queries with CQRS
The microservice architecture
structures
an application as a
set of loosely coupled
services
@crichardson
API
Service = independently deployable
component
Operations
Event
Publisher
Commands
Queries
Synchronous
REST...
@crichardson
Microservices enable
continuous delivery/deployment
Process:
Continuous delivery/deployment
Organization:
Sma...
@crichardson
Let’s imagine that you are
building an online store API
createCustomer(creditLimit)
createOrder(customerId, o...
@crichardson
Order
Service
createCustomer()
createOrder()
findOrdersForCustomer()
findRecentCustomers()
API Gateway
createCu...
@crichardson
No ACID transactions that span
services
BEGIN TRANSACTION
…
SELECT ORDER_TOTAL
FROM ORDERS WHERE CUSTOMER_ID ...
@crichardson
Querying across services is
not straightforward
SELECT *
FROM CUSTOMER c, ORDER o
WHERE
c.id = o.ID
AND c.id ...
@crichardson
Agenda
Transactions, queries and microservices
Managing transactions with sagas
Implementing queries with CQRS
@crichardson
From a 1987 paper
@crichardson
Saga
Use Sagas instead of 2PC
Distributed transaction
Service A Service B
Service A
Local
transaction
Service...
@crichardson
Order Service
Create Order Saga
Local transaction
Order
state=PENDING
createOrder()
Customer Service
Local tr...
@crichardson
Saga design challenges
API design
Synchronous REST API initiates asynchronous saga
When to send back a respon...
How do the saga participants
communicate?
Synchronous
communication, e.g. REST
= temporal coupling
Client and server need ...
@crichardson
Collaboration using asynchronous,
broker-based messaging
Order Service
Customer
Service
….
Message broker
@crichardson
About the message broker
At least once delivery
Ensures a saga completes when its participants are
temporaril...
@crichardson
Saga step = a transaction
local to a service
Service
Database Message Broker
update publish message/event
How...
@crichardson
How to sequence the saga
transactions?
After the completion of transaction Ti “something” must
decide what st...
@crichardson
Choreography: distributed decision making
vs.
Orchestration: centralized decision making
@crichardson
Agenda
Overview
Choreography
Orchestration
Transactional
messaging
Transactions, queries and microservices
Ma...
@crichardson
Choreography-based coordination
using events
Order cancelled
Order
Service
Customer
Service
DB DB
Order creat...
@crichardson
Message broker
Choreography-based Create Order
Saga
Order created
Credit Reserved
Credit Limit Exceeded
Creat...
@crichardson
API
Order Service
Operations
createOrder()
Event
Publisher
Order
events
Event
Subscriber
Customer
Events
Serv...
@crichardson
API
Customer Service
Operations
createCustomer()
Event
Publisher
Customer
Events
Event
Subscriber
Order
Event...
Benefits and drawbacks of
choreography
Benefits
Simple, especially when using
event sourcing
Participants are loosely couple...
@crichardson
Overview
Choreography
Orchestration
Transactional
messaging
Agenda
Transactions, queries and microservices
Ma...
@crichardson
Order Service
Orchestration-based coordination using
command messages
Local transaction
Order
state=PENDING
c...
@crichardson
Request/asynchronous reply-
based communication
Release credit
Order
Service
Customer
Service
DB
DB
Reserve c...
@crichardson
A saga (orchestrator)
is a persistent object
that
tracks the state of the saga
and
invokes the participants
Saga orchestrator behavior
On create:
Invokes a saga participant
Persists state in database
Wait for a reply
On reply:
Loa...
@crichardson
Order Service
CreateOrderSaga orchestrator
Customer Service
Create Order
Customer
creditLimit
creditReservati...
@crichardson
API
Order Service
Operations
createOrder()
API
Client
Invokes
Customer
Service
Service
Database
reserveCredit...
@crichardson
API
Customer Service
Operations
createCustomer()
reserveCredit()
releaseCredit()
Service
Database
Simple
API
@crichardson
Eventuate Tram Sagas
Open-source Saga orchestration framework
Currently for Java
https://github.com/eventuate...
Benefits and drawbacks of
orchestration
Benefits
Centralized coordination
logic is easier to understand
Reduced coupling, e....
@crichardson
Overview
Choreography
Orchestration
Transactional
messaging
Agenda
Transactions, queries and microservices
Ma...
@crichardson
Messaging must be
transactional
Service
Database Message Broker
update publish
How to
make atomic
without 2PC?
Publish to message broker
first?
Guarantees atomicity
BUT
Service can’t read its own
writes
Difficult to write business
logi...
@crichardson
Option: Event sourcing
=
Event centric approach to
business logic and persistence
http://eventuate.io/
@crichardson
Event sourcing: persists an object
as a sequence of events
Event table
Entity type
Event
id
Entity
id
Event
d...
@crichardson
Replay events to recreate in memory state
Order
state
apply(event)
Event table
Entity type
Event
id
Entity
id...
@crichardson
FYI:
Apache Kafka != event store
@crichardson
Event sourcing guarantees: state
change event is published
Event table
Entity type
Event
id
Entity
id
Event
d...
@crichardson
Preserves history of domain objects
Supports temporal queries
Simplifies retroactive correction
Built-in audit...
@crichardson
Unfamiliar programming model
Evolving the schema of long-lived events
Event store only supports PK-based acce...
@crichardson
Good fit for choreography-based sagas
BUT orchestration is more challenging
Use event handler to translate eve...
@crichardson
Option:
Traditional persistence
(JPA, MyBatis,…)
+
Transactional outbox pattern
https://github.com/eventuate-...
@crichardson
Spring Data for JPA example
Publish event
Save order
http://eventuate.io/exampleapps.html
@crichardson
Customer Service: consuming
domain events…
https://github.com/eventuate-tram/eventuate-tram-examples-customer...
@crichardson
Atomically updating state and
publishing events
ACID
transaction
See BASE: An Acid Alternative, http://bit.ly...
@crichardson
Transaction log tailing
Order
Service
Datastore
ORDER table
Transaction log
Update
Transaction log
miner
Mess...
@crichardson
Polling the message table
Simple
Works for all databases
BUT what about polling frequency
MESSAGE
Table
Messa...
@crichardson
Agenda
Transactions, queries and microservices
Managing transactions with sagas
Implementing queries with CQRS
@crichardson
Queries often retrieve data
owned by multiple services
@crichardson
API Composition pattern
Customer Service
Customer
…
Order Service
Order
…
API Gateway
findOrdersForCustomer(cu...
@crichardson
Find recent, valuable
customers
SELECT *
FROM CUSTOMER c, ORDER o
WHERE
c.id = o.ID
AND o.ORDER_TOTAL > 10000...
API Composition would be
inefficient
1 + N strategy:
Fetch recent customers
Iterate through customers
fetching their shippe...
@crichardson
Using events to update a queryable
replica = CQRS
Order
Service
Customer
Service
Order events
Customer events...
@crichardson
API
Order Service
Operations
createOrder()
Event
Publisher
Order
events
Service
Database
@crichardson
API
Customer Service
Operations
createCustomer()
Event
Publisher
Customer
events
Service
Database
@crichardson
Customer Order View Service
Operations
findOrder()
findOrders….()
Event
Subscriber
Order
Events
Service
Databas...
@crichardson
Query side data model
Command Query Responsibility
Segregation (CQRS)
Command side data model
Commands
Aggreg...
@crichardson
Queries database (type)
Command side
POST
PUT
DELETE
Aggregate
Event Store/Message Broker
Events
Query side
G...
@crichardson
A CQRS view can be part of a
service
Restaurant
Service
Restaurant events channel
Transactional
Source of tru...
@crichardson
Use a CQRS replica to validate
commands
Order Service
createOrder()
Customer
Service
Orders
Customers
creditL...
@crichardson
CQRS views are disposable
Rebuild when needed from source of truth
Using event sourcing
(Conceptually) replay...
@crichardson
Handling replication lag
Lag between updating command side and CQRS view
Risk of showing stale data to user
E...
@crichardson
Summary
Use synchronous protocols, e.g. REST or gRPC:
External APIs
(Read only) API Composition
Use asynchron...
@crichardson
@crichardson chris@chrisrichardson.net
http://learn.microservices.io
Questions?
40% discount with code
ctwmuc...
Upcoming SlideShare
Loading in …5
×

Mucon: Not Just Events: Developing Asynchronous Microservices

22,021 views

Published on

The microservice architecture functionally decomposes an application into a set of services. Each service has its own private database that’s only accessible indirectly through the services API. Consequently, implementing queries and transactions that span multiple services is challenging. In this presentation, you will learn how to solve these distributed data management challenges using asynchronous messaging. Chris will share with you how to implement transactions using sagas, which are sequences of local transactions. You will learn how to coordinate sagas using either events or command messages. Chris will also explore how to implement queries using Command Query Responsibility Segregation (CQRS), which uses events to maintain easily queried replicas.

Published in: Software
  • Be the first to comment

Mucon: Not Just Events: Developing Asynchronous Microservices

  1. 1. @crichardson Not Just Events: Developing Asynchronous Microservices  Chris Richardson Founder of Eventuate.io Founder of the original CloudFoundry.com Author of POJOs in Action and Microservices Patterns @crichardson chris@chrisrichardson.net http://learn.microservices.io Copyright © 2018 Chris Richardson Consulting, Inc. All rights reserved
  2. 2. @crichardson Presentation goal Using asynchronous messaging to implement transactions and queries in a microservice architecture
  3. 3. @crichardson Presentation goal Microservices != REST Microservices != Events Microservices != Event Sourcing Apache Kafka != Event Store
  4. 4. @crichardson About Chris
  5. 5. @crichardson About Chris Consultant and trainer focussed on helping organizations adopt the microservice architecture (http://www.chrisrichardson.net/)
  6. 6. @crichardson About Chris Founder of a startup that is creating an open-source/SaaS platform that simplifies the development of transactional microservices (http://eventuate.io)
  7. 7. @crichardson About Chris https://www.manning.com/books/microservices-patterns 40% discount with code ctwmucon18
  8. 8. About Chris: microservices.io Microservices pattern language Articles Code examples Microservices Assessment Platform - coming soon
  9. 9. @crichardson Agenda Transactions, queries and microservices Managing transactions with sagas Implementing queries with CQRS
  10. 10. The microservice architecture structures an application as a set of loosely coupled services
  11. 11. @crichardson API Service = independently deployable component Operations Event Publisher Commands Queries Synchronous REST/gRPC Asynchronous Messaging Events Event Subscriber API Client Invokes Operations Events Service Database
  12. 12. @crichardson Microservices enable continuous delivery/deployment Process: Continuous delivery/deployment Organization: Small, agile, autonomous, cross functional teams Architecture: Microservice architecture Enables Enables Enables Successful Software Development Services = testability and deployability Teams own services
  13. 13. @crichardson Let’s imagine that you are building an online store API createCustomer(creditLimit) createOrder(customerId, orderTotal) findOrdersForCustomer(customerId) findRecentCustomers() Order Management Customer Management REST API …
  14. 14. @crichardson Order Service createCustomer() createOrder() findOrdersForCustomer() findRecentCustomers() API Gateway createCustomer() createOrder() Order DatabaseCustomer Database Order tableCustomer table REST API REST API Essential for loose coupling Must reserve customer’s credit Retrieve data from both services Customer Service REST API availableCredit …. OrderTotal ….
  15. 15. @crichardson No ACID transactions that span services BEGIN TRANSACTION … SELECT ORDER_TOTAL FROM ORDERS WHERE CUSTOMER_ID = ? … SELECT CREDIT_LIMIT FROM CUSTOMERS WHERE CUSTOMER_ID = ? … INSERT INTO ORDERS … … COMMIT TRANSACTION Private to the Order Service Private to the Customer Service Distributed transactions
  16. 16. @crichardson Querying across services is not straightforward SELECT * FROM CUSTOMER c, ORDER o WHERE c.id = o.ID AND c.id = ? Private to Customer Service Private to Order Service Find customer and their orders
  17. 17. @crichardson Agenda Transactions, queries and microservices Managing transactions with sagas Implementing queries with CQRS
  18. 18. @crichardson From a 1987 paper
  19. 19. @crichardson Saga Use Sagas instead of 2PC Distributed transaction Service A Service B Service A Local transaction Service B Local transaction Service C Local transaction X Service C https://microservices.io/patterns/data/saga.html
  20. 20. @crichardson Order Service Create Order Saga Local transaction Order state=PENDING createOrder() Customer Service Local transaction Customer reserveCredit() Order Service Local transaction Order state=APPROVED approve order() createOrder() Initiates saga
  21. 21. @crichardson Saga design challenges API design Synchronous REST API initiates asynchronous saga When to send back a response? Rollback compensating transactions Sagas are ACD - No I Sagas are interleaved anomalies, such as lost updates Must use countermeasures https://www.slideshare.net/chris.e.richardson/saturn-2018-managing-data-consistency-in-a-microservice-architecture-using-sagas
  22. 22. How do the saga participants communicate? Synchronous communication, e.g. REST = temporal coupling Client and server need to be both available Customer Service fails retry provided it’s idempotent Order Service fails Oops Order Service createOrder() REST Customer Service reserveCredit() REST
  23. 23. @crichardson Collaboration using asynchronous, broker-based messaging Order Service Customer Service …. Message broker
  24. 24. @crichardson About the message broker At least once delivery Ensures a saga completes when its participants are temporarily unavailable Ordered delivery Mechanism for scaling consumers that preserves ordering e.g. Apache Kafka consumer group ActiveMQ message group
  25. 25. @crichardson Saga step = a transaction local to a service Service Database Message Broker update publish message/event How to make atomic without 2PC?
  26. 26. @crichardson How to sequence the saga transactions? After the completion of transaction Ti “something” must decide what step to execute next Success: which T(i+1) - branching Failure: C(i - 1)
  27. 27. @crichardson Choreography: distributed decision making vs. Orchestration: centralized decision making
  28. 28. @crichardson Agenda Overview Choreography Orchestration Transactional messaging Transactions, queries and microservices Managing transactions with sagas Implementing queries with CQRS
  29. 29. @crichardson Choreography-based coordination using events Order cancelled Order Service Customer Service DB DB Order created Domain event Subscriber updates its DB Abstracts message broker Message channel
  30. 30. @crichardson Message broker Choreography-based Create Order Saga Order created Credit Reserved Credit Limit Exceeded Create Order OR Customer creditLimit creditReservations Order state total create() reserveCredit() approve()/ reject() Order events channel Customer events channel Order Service Customer Service
  31. 31. @crichardson API Order Service Operations createOrder() Event Publisher Order events Event Subscriber Customer Events Service Database
  32. 32. @crichardson API Customer Service Operations createCustomer() Event Publisher Customer Events Event Subscriber Order Events Service Database
  33. 33. Benefits and drawbacks of choreography Benefits Simple, especially when using event sourcing Participants are loosely coupled Drawbacks Cyclic dependencies - services listen to each other’s events, e.g. Customer Service must know about all Order events that affect credit Overloads domain objects, e.g. Order and Customer know too much Events = indirect way to make something happen https://github.com/eventuate-examples/eventuate-examples-java-customers-and-orders
  34. 34. @crichardson Overview Choreography Orchestration Transactional messaging Agenda Transactions, queries and microservices Managing transactions with sagas Implementing queries with CQRS
  35. 35. @crichardson Order Service Orchestration-based coordination using command messages Local transaction Order state=PENDING createOrder() Customer Service Local transaction Customer reserveCredit() Order Service Local transaction Order state=APPROVED approve order() createOrder() CreateOrderSaga InvokesInvokesInvokes
  36. 36. @crichardson Request/asynchronous reply- based communication Release credit Order Service Customer Service DB DB Reserve credit Command Customer service command channel Create Order saga Reply channel Reply Orchestrator Update Credit
  37. 37. @crichardson A saga (orchestrator) is a persistent object that tracks the state of the saga and invokes the participants
  38. 38. Saga orchestrator behavior On create: Invokes a saga participant Persists state in database Wait for a reply On reply: Load state from database Determine which saga participant to invoke next Invokes saga participant Updates its state Persists updated state Wait for a reply …
  39. 39. @crichardson Order Service CreateOrderSaga orchestrator Customer Service Create Order Customer creditLimit creditReservations ... Order state total… reserveCredit() CreateOrder Saga OrderService create() create() approve() Credit Reserved Customer command channel Saga reply channel
  40. 40. @crichardson API Order Service Operations createOrder() API Client Invokes Customer Service Service Database reserveCredit() releaseCredit()
  41. 41. @crichardson API Customer Service Operations createCustomer() reserveCredit() releaseCredit() Service Database Simple API
  42. 42. @crichardson Eventuate Tram Sagas Open-source Saga orchestration framework Currently for Java https://github.com/eventuate-tram/eventuate-tram-sagas https://github.com/eventuate-tram/eventuate-tram-sagas- examples-customers-and-orders
  43. 43. Benefits and drawbacks of orchestration Benefits Centralized coordination logic is easier to understand Reduced coupling, e.g. Customer Service knows less. Simply has API for managing available credit. Reduces cyclic dependencies Drawbacks Risk of smart sagas directing dumb services
  44. 44. @crichardson Overview Choreography Orchestration Transactional messaging Agenda Transactions, queries and microservices Managing transactions with sagas Implementing queries with CQRS
  45. 45. @crichardson Messaging must be transactional Service Database Message Broker update publish How to make atomic without 2PC?
  46. 46. Publish to message broker first? Guarantees atomicity BUT Service can’t read its own writes Difficult to write business logic Service Database Message Broker update publish
  47. 47. @crichardson Option: Event sourcing = Event centric approach to business logic and persistence http://eventuate.io/
  48. 48. @crichardson Event sourcing: persists an object as a sequence of events Event table Entity type Event id Entity id Event data Order 902101 …OrderApproved Order 903101 …OrderShipped Event type Order 901101 …OrderCreated Order create() approve() ship() Event Store
  49. 49. @crichardson Replay events to recreate in memory state Order state apply(event) Event table Entity type Event id Entity id Event data Order 902101 …OrderApproved Order 903101 …OrderShipped Event type Order 901101 …OrderCreated Event Store Load events by ID and call apply() Instantiate with default constructor Event store = database
  50. 50. @crichardson FYI: Apache Kafka != event store
  51. 51. @crichardson Event sourcing guarantees: state change event is published Event table Entity type Event id Entity id Event data Order 902101 …OrderApproved Order 903101 …OrderShipped Event type Order 901101 …OrderCreated Event Store Customer Service Subscribe Event store = message broker
  52. 52. @crichardson Preserves history of domain objects Supports temporal queries Simplifies retroactive correction Built-in auditing Other benefits of event sourcing
  53. 53. @crichardson Unfamiliar programming model Evolving the schema of long-lived events Event store only supports PK-based access requires CQRS less consistent reads Drawbacks of event sourcing
  54. 54. @crichardson Good fit for choreography-based sagas BUT orchestration is more challenging Use event handler to translate event into command/reply message Drawbacks of event sourcing
  55. 55. @crichardson Option: Traditional persistence (JPA, MyBatis,…) + Transactional outbox pattern https://github.com/eventuate-tram/eventuate-tram-core
  56. 56. @crichardson Spring Data for JPA example Publish event Save order http://eventuate.io/exampleapps.html
  57. 57. @crichardson Customer Service: consuming domain events… https://github.com/eventuate-tram/eventuate-tram-examples-customers-and-orders Subscribe to event
  58. 58. @crichardson Atomically updating state and publishing events ACID transaction See BASE: An Acid Alternative, http://bit.ly/ebaybase DELETE ? Customer Service ORDER_ID CUSTOMER_ID TOTAL 99 CUSTOMER_CREDIT_RESERVATIONS table 101 1234 ID TYPE DATA DESTINATION MESSAGE table 84784 CreditReserved {…} … INSERT INSERT Message Publisher QUERY Message Broker Publish Local transaction reserveCredit()
  59. 59. @crichardson Transaction log tailing Order Service Datastore ORDER table Transaction log Update Transaction log miner Message Broker Publish Changes MySQL binlog Postgres WAL AWS DynamoDB table streams MongoDB change streams
  60. 60. @crichardson Polling the message table Simple Works for all databases BUT what about polling frequency MESSAGE Table Message Publisher Message Broker SELECT * FROM MESSAGE… UPDATE MESSAGE
  61. 61. @crichardson Agenda Transactions, queries and microservices Managing transactions with sagas Implementing queries with CQRS
  62. 62. @crichardson Queries often retrieve data owned by multiple services
  63. 63. @crichardson API Composition pattern Customer Service Customer … Order Service Order … API Gateway findOrdersForCustomer(customerId) GET /customer/id GET /orders?customerId=id FK query! https://microservices.io/patterns/data/api-composition.html
  64. 64. @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 …. is even more difficult!
  65. 65. API Composition would be inefficient 1 + N strategy: Fetch recent customers Iterate through customers fetching their shipped orders Lots of round trips high-latency Alternative strategy: Fetch recent customers Fetch recent orders Join 2 roundtrips but potentially large datasets inefficient
  66. 66. @crichardson Using events to update a queryable replica = CQRS Order Service Customer Service Order events Customer events findCustomersAndOrders() Order events channel Customer events channel Customer Order View Service Replica View Database https://microservices.io/patterns/data/cqrs.html
  67. 67. @crichardson API Order Service Operations createOrder() Event Publisher Order events Service Database
  68. 68. @crichardson API Customer Service Operations createCustomer() Event Publisher Customer events Service Database
  69. 69. @crichardson Customer Order View Service Operations findOrder() findOrders….() Event Subscriber Order Events Service Database Customer Events
  70. 70. @crichardson Query side data model Command Query Responsibility Segregation (CQRS) Command side data model Commands Aggregate Message broker or Event Store Events Queries (Materialized) View Events POST PUT DELETE GET
  71. 71. @crichardson Queries database (type) Command side POST PUT DELETE Aggregate Event Store/Message Broker Events Query side GET /customers/id MongoDB Query side GET /orders?text=xyz ElasticSearch Query side GET … Neo4j
  72. 72. @crichardson A CQRS view can be part of a service Restaurant Service Restaurant events channel Transactional Source of truth CQRS replica for geo/text search createRestaurant() … findRestaurantsNear(location, keywords) MySQL Elastic
 Search
  73. 73. @crichardson Use a CQRS replica to validate commands Order Service createOrder() Customer Service Orders Customers creditLimit availableCredit Customer events Replica Checks available credit without invoking Customer Service
  74. 74. @crichardson CQRS views are disposable Rebuild when needed from source of truth Using event sourcing (Conceptually) replay all events from beginning of time Using traditional persistence “ETL” from source of truth databases
  75. 75. @crichardson Handling replication lag Lag between updating command side and CQRS view Risk of showing stale data to user Either: Update UI/client-side model without querying Use updated aggregate version to “wait” for query view to be updated
  76. 76. @crichardson Summary Use synchronous protocols, e.g. REST or gRPC: External APIs (Read only) API Composition Use asynchronous messaging to solve distributed data management problems Services publish events to implement choreography-based sagas queries using CQRS views Services publish events using either event sourcing or explicit publishing Services send command/reply messages to implement orchestration-based sagas
  77. 77. @crichardson @crichardson chris@chrisrichardson.net http://learn.microservices.io Questions? 40% discount with code ctwmucon18

×