#hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the...
-
Upload
chris-richardson -
Category
Software
-
view
5.972 -
download
2
Transcript of #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the...
![Page 1: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/1.jpg)
@crichardson
Events on the outside, on the inside and at the coreChris Richardson
Founder of Eventuate.io Founder of the original CloudFoundry.com Author of POJOs in Action
@crichardson [email protected] http://microservices.io http://eventuate.io http://plainoldobjects.com
![Page 2: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/2.jpg)
@crichardson
Presentation goal
Events play a key role in applications
Event sourcing enables the event-driven enterprise
![Page 3: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/3.jpg)
@crichardson
About Chris
![Page 4: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/4.jpg)
@crichardson
About Chris
Consultant and trainer focusing on
microservices (public class: April 28th, Oakland, CA)
http://www.chrisrichardson.net/
![Page 5: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/5.jpg)
@crichardson
About Chris
Founder of a startup that is creating
a platform that makes it easy for application developers to write
microservices
http://eventuate.io
![Page 6: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/6.jpg)
@crichardson
For more information
http://bit.ly/eventsfeb24
![Page 7: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/7.jpg)
@crichardson
Agenda
Events on the outside
Events on the inside
Events at the core with event sourcing
Designing event-centric domain model
![Page 8: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/8.jpg)
@crichardson
Events on the outside
Application A
Application B
Application C
Event X
Event YEvent Z
![Page 9: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/9.jpg)
@crichardson
What’s an event?
http://www.merriam-webster.com/dictionary/event
![Page 10: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/10.jpg)
@crichardson
Examples of events
![Page 11: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/11.jpg)
@crichardson
Instacart: event-driven grocery shopping
![Page 12: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/12.jpg)
@crichardson
An event is produced when…
Creation or update of a business object
Attempt to violate a business rule
![Page 13: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/13.jpg)
@crichardson
How to reliably generate events?
More on that later…
![Page 14: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/14.jpg)
@crichardson
Who consumes an event?
Order Application
HumanNotification Service
Dashboard/ Monitoring
Shipping Application
OrderCreated
Email SMS …
![Page 15: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/15.jpg)
@crichardson
How to deliver events?
![Page 16: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/16.jpg)
@crichardson
Inside the firewall
![Page 17: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/17.jpg)
@crichardson
Enterprise integration patterns
http://www.enterpriseintegrationpatterns.com/patterns/messaging/
![Page 18: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/18.jpg)
@crichardson
messaging system
Messaging-based IPC
Sender RecipientChannelmessage
![Page 19: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/19.jpg)
@crichardson
Example messaging systems
![Page 20: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/20.jpg)
@crichardson
Outside the firewall
![Page 21: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/21.jpg)
@crichardson
Polling for events
HTTP
Periodically poll for events
Atom Publishing Protocol (AtomPub)
Based on HTTP
Head is constantly changing
Tail is immutable and can be efficiently cached
High-latency, inefficient
![Page 22: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/22.jpg)
@crichardson
Using WebSockets
Browser
Web Socket
STOMP
Client application
Service
Web Socket
STOMP
ApplicationSUBSCRIBE
MESSAGEMESSAGE
Low latency, more efficient, but what about past events?
![Page 23: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/23.jpg)
@crichardson
Webhooks = user-defined HTTP callback
Client Service
register(events, callbackUrl)
POST callbackUrl
POST callbackUrl
…
https://en.wikipedia.org/wiki/WebhookLow latency, more efficient, but what
about past events?
![Page 24: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/24.jpg)
@crichardson
WebHooks =
web friendly publish/subscribe
![Page 25: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/25.jpg)
@crichardson
Github webhookshttps://developer.github.com/webhooks/
Installed on an organization or repository
e.g. POST /repos/:owner/:repo/hooks
Available events:
push - push to a repository
fork - repository is forked
pull_request - assigned, unassigned, …
push - push to a repository
…
![Page 26: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/26.jpg)
@crichardson
Twilio - Telephony and SMS as a service
Twilio Your Application
TwiML doc
HTTP GET/POST
REST API
Manage resourcesSend SMS
Initiate voice calls
Webhooks handle incoming SMS and voice calls
VoiceSMS
Phone number ⇒ SMS URL + VOICE URL
![Page 27: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/27.jpg)
@crichardson
Integration hubs - Zapier, IFTTTApplication abstraction:
Triggers - events published by application: polling or Webhooks
Action - operation supported by application, e.g. REST API end points
![Page 28: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/28.jpg)
@crichardson
The event-driven enterprise
App A App BApp X
App Y
Firewall
Message Broker
webhooks
WebSockets
AtomPub
App Z App C
MsgBrokerClient Msg
BrokerClient
MsgBrokerClient
App D
MsgBrokerClient
Inside the firewallOutside the firewall
![Page 29: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/29.jpg)
@crichardson
Agenda
Events on the outside
Events on the inside
Events at the core with event sourcing
Designing event-centric domain model
![Page 30: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/30.jpg)
@crichardson
Events on the insideApplication
Service A
Service B
Service C
Event X
Event YEvent Z
Event X
Event Y
![Page 31: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/31.jpg)
@crichardson
Traditional monolithic architecture
Simple to develop
test deploy scale
Shopping Cart
CustomersOrders
Mobile client RESTAPI
Browser WebUI
MessageBroker
Adapter
MySQLAdapter
RDBMS
…
Message Broker
![Page 32: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/32.jpg)
@crichardson
But that leads* to monolithic hell
For large and/or complex applications…
![Page 33: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/33.jpg)
@crichardson
Today: use a microservice, polyglot architecture
Orders
Customers
…Shopping UI
Mobile Client
Browser
API Gateway
Order management
RESTAPI
CustomerManagement
RESTAPI
….
RESTAPI
OrderDatabase
(MongoDB)MongoDBAdapter
CustomerDatabase(Sharded MySQL)
MySQLAdapter
![Page 34: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/34.jpg)
@crichardson
But now we have distributed data management
problems
![Page 35: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/35.jpg)
@crichardson
Example: placing an order
Order Service Customer Service
Order Database
Customer Database
Order #1 Customer #1
No 2PC
No ACID
NoSQL SQL
![Page 36: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/36.jpg)
@crichardson
Customer management
How to maintain invariants?
Order management
Order Service
placeOrder()
Customer Service
updateCreditLimit()
Customer
creditLimit ...
has ordersbelongs toOrder
total
Invariant: sum(open order.total) <= customer.creditLimit
?
![Page 37: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/37.jpg)
@crichardson
Use an event-driven architecture
Services publish events when something important happens, e.g. state changes
Services subscribe to events and update their state
Maintain eventual consistency across multiple aggregates (in multiple datastores)
Synchronize replicated data
![Page 38: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/38.jpg)
@crichardson
Event-driven application architectureApplication
Service A Service B
Message Broker
Service C
MsgBrokerClient
MsgBrokerClient
MsgBrokerClient
Service D
MsgBrokerClient
![Page 39: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/39.jpg)
@crichardson
Order ManagementOrder
id : 4567 total: 343 state = CREATED
Customer Management
Customer creditLimit : 12000 creditReservations: {}
Customer creditLimit : 12000 creditReservations: { 4567 -> 343}
Order id : 4567 total: 343 state = OPEN
Eventually consistent credit checking
Message Bus
createOrder()
Publishes:Subscribes to:
Subscribes to:
publishes:
OrderCreatedEvent
CreditReservedEvent
OrderCreatedEvent CreditReservedEvent
![Page 40: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/40.jpg)
@crichardson
Now there are two problems to solve….
![Page 41: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/41.jpg)
@crichardson
Problem #1: How to design eventually consistent business logic?
More on that later….
![Page 42: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/42.jpg)
@crichardson
Problem #2: How to atomically update database and publish an event
Order Service
Order Database
Message Broker
insert Order
publish OrderCreatedEvent
dual write problem
?
![Page 43: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/43.jpg)
@crichardson
Failure = inconsistent system
Order Service
Order Database
Message Broker
insert Order
publish OrderCreatedEvent
X
![Page 44: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/44.jpg)
@crichardson
Two-phase commitX
![Page 45: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/45.jpg)
@crichardson
Agenda
Events on the outside
Events on the inside
Events at the core with event sourcing
Designing event-centric domain model
![Page 46: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/46.jpg)
@crichardson
Just publish events
Application
Database
Message Broker
update
publish
X
![Page 47: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/47.jpg)
@crichardson
Event sourcingFor each aggregate (business entity):
Identify (state-changing) domain events
Define Event classes
For example,
ShoppingCart: ItemAddedEvent, ItemRemovedEvent, OrderPlacedEvent
Order: OrderCreated, OrderCancelled, OrderApproved, OrderRejected, OrderShipped
![Page 48: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/48.jpg)
@crichardson
Persists events NOT current state
Order
status ….
101 ACCEPTED
Order tableX
![Page 49: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/49.jpg)
@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 50: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/50.jpg)
@crichardson
Replay events to recreate state
Order
state
OrderCreated(…) OrderAccepted(…) OrderShipped(…)
Events
Periodically snapshot to avoid loading all events
![Page 51: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/51.jpg)
@crichardson
The present is a fold over history
currentState = foldl(applyEvent, initialState, events)
![Page 52: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/52.jpg)
@crichardson
Events at the core
Aggregate A
Aggregate B
Aggregate C
Event X
Event YEvent ZEvent Z
Event Y
Service
![Page 53: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/53.jpg)
@crichardson
Domain logic = event-driven aggregates
CustomerAggregateOrder
Aggregate
Order CreatedEvent Check Credit
Command
Credit ReservedEvent
Approve OrderCommand
Create OrderCommand
External request
Emits events Event ⇒ Command
![Page 54: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/54.jpg)
@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
apply(newEvents)
![Page 55: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/55.jpg)
@crichardson
Event Store publishes events consumed by other services
Event Store
Event Subscriber
subscribe(EventTypes)
publish(event)
publish(event)
Customer
update()
Customer Service
![Page 56: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/56.jpg)
@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 57: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/57.jpg)
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 58: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/58.jpg)
@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 59: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/59.jpg)
@crichardson
Drawbacks of event sourcing…
Requires 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
…
![Page 60: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/60.jpg)
@crichardson
… Drawbacks of event sourcing
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 61: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/61.jpg)
@crichardson
Agenda
Events on the outside
Events on the inside
Events at the core with event sourcing
Designing event-centric domain model
![Page 62: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/62.jpg)
@crichardson
Use the familiar building blocks of DDD
Entity
Value object
Services
Repositories
Aggregates ⟸ essential
![Page 63: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/63.jpg)
About AggregatesGraph consisting of a root entity and one or more other entities and value objects
Each core business entity = Aggregate: e.g. customer, Account, Order, Product, ….
Reference other aggregate roots via primary key
Often contains partial copy of other aggregates’ data
Order
OrderLine Item
quantity productId productName productPrice
customerId
Address
street city …
![Page 64: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/64.jpg)
@crichardson
Domain model = collection of loosely connected aggregates
Order
OrderLine Item
quantity
…
Addressstreet city …
Customer
Productname price
![Page 65: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/65.jpg)
@crichardson
Product service
Customer serviceOrder service
Easily partition into microservices
Order
OrderLine Item
quantity
…
Addressstreet city …
Customer
Productname price
![Page 66: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/66.jpg)
@crichardson
Transaction = processing one command by one aggregate
No opportunity to update multiple aggregates within a transaction ⇒ event driven eventual consistency between aggregates
If an update must be atomic (i.e. no compensating transaction) then it must be handled by a single aggregate
Therefore, aggregate granularity is important
![Page 67: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/67.jpg)
@crichardson
Product service
Customer serviceOrder service
Transaction scope = service
Order
OrderLine Item
quantity
…
Addressstreet city …
Customer
Productname price
![Page 68: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/68.jpg)
@crichardson
Aggregate granularity
Consistency Scalability/ User experience
Customer
Order
Product
Customer
Order
Product
Customer
Order
Product
![Page 69: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/69.jpg)
Designing domain eventsRecord state changes for an aggregate
Part of the public API of the domain model ProductAddedToCart
id : TimeUUID senderId: UUID productId productName productPrice …
Required by aggregate
Enrichment: Useful for
consumers
Event metadata
![Page 70: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/70.jpg)
@crichardson
Example event
![Page 71: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/71.jpg)
@crichardson
Designing commandsCreated by a service from incoming request
Processed by an aggregate
Immutable
Contains value objects for
Validating request
Creating event
Auditing user activity
![Page 72: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/72.jpg)
@crichardson
Example command
![Page 73: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/73.jpg)
@crichardson
Various programming models
“Traditional Java” mutable object-oriented domain objects
https://github.com/cer/event-sourcing-examples/tree/master/java-spring
Functional Scala with immutable domain objects
https://github.com/cer/event-sourcing-using-scala-typeclasses
Hybrid OO/Functional Scala with immutable domain objects
https://github.com/cer/event-sourcing-examples/tree/master/scala-spring
![Page 74: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/74.jpg)
@crichardson
OO = State + Behavior
creditLimit creditReservations : Map<OrderId, Money>
Customer
List<Event> process(CreateCustomerCommand cmd) { … } List<Event> process(ReserveCreditCommand cmd) { … } … void apply(CustomerCreatedEvent anEvent) { … } void apply(CreditServedEvent anEvent) { … } …
State
Behavior
![Page 75: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/75.jpg)
@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 … new CreditReservedCredit(); }
public void apply( CreditReservedCredit event) { // update state this.xyz = event.xyz }
![Page 76: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/76.jpg)
@crichardson
Real-time, collaborative Kanban Board
![Page 77: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/77.jpg)
@crichardson
Kanban domain model
Board
title createdBy …
Task
title state …
![Page 78: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/78.jpg)
@crichardson
ArchitectureCreate/update boards
and tasks
Change notifications Materialized views
Event Store
![Page 79: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/79.jpg)
@crichardson
Request and event flow
Eventuate event store
Kanban Server
AngularJS application POST
/tasks/xyz/start
Task xyz
POST /entity/….
Task StartedAngularJS
applicationWebSocket Message
STOMP Message
![Page 80: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/80.jpg)
@crichardson
Demo
![Page 81: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/81.jpg)
@crichardson
Summary
Events are a central to modern applications
Events integrate applications
Events maintain data consistency in a microservices architecture
⇒
Build events into the core of your application using event sourcing
![Page 82: #hacksummit 2016 - event-driven microservices – Events on the outside, on the inside and at the core](https://reader031.fdocuments.us/reader031/viewer/2022030316/58742fdf1a28ab72188b7591/html5/thumbnails/82.jpg)
@crichardson
For more information
http://bit.ly/eventsfeb24