SlideShare a Scribd company logo
Should you be using an
Event Driven Architecture?
Jeppe Cramon - @jeppec
Cloud Create ApS
@jeppec
@jeppec
Check-out microcph.dk
for more details!
@jeppec
“Example isn’t another way to teach,
it is the only way to teach”
Albert Einstein
@jeppec
Let’s look at Online Shopping
@jeppec
Most sites follow a
similar pattern
@jeppec
save(order)
@jeppec
public class OrderService {
public void save(Order order) {
orderRepository.add(order);
if (inventoryService.areOrderItemsInStock(order)) {
order.setStatus(OrderStatus.ItemsInStock);
shippingService.startPackagingOrder(order);
emailService.send(generateOrderOrderItemsInStockEmail(order));
} else {
order.setStatus(OrderStatus.NotAllItemsInStock);
emailService.send(generateOrderItemsNotInStockEmail(order));
executeMethod(OrderService::checkOrderInventoryStatus, Period.ofDays(1));
}
}
public void checkOrderInventoryStatus(OrderId orderId) {
Order order = orderRepository.load(orderId);
if (inventoryService.areOrderItemsInStock(order)) {
order.setStatus(OrderStatus.ItemsInStock);
shippingService.startPackagingOrder(order);
emailService.send(generateOrderOrderItemsInStockEmail(order));
} else {
executeMethod(OrderService::checkOrderInventoryStatus, Period.ofDays(1));
}
}
Side effect. What happens if we call save() twice?
@jeppec
public class OrderService {
public void save(Order order) {
orderRepository.add(order);
if (inventoryService.areOrderItemsInStock(order)) {
order.setStatus(OrderStatus.ItemsInStock);
shippingService.startPackagingOrder(order);
…
@jeppec
Let’s decouple Order- and
Inventory Service further
public class OrderService {
public void save(Order order) {
orderRepository.add(order);
if (inventoryService.areOrderItemsInStock(order)) {
order.setStatus(OrderStatus.ItemsInStock);
shippingService.startPackagingOrder(order);
@jeppec
public class OrderService {
public void save(Order order) {
orderRepository.add(order);
List<ProductId> productIdsOutOfStock = inventoryService.checkProductStockStatus(
order.orderLines.toMap(OrderLine::productId, OrderLine::quantity));
if (productIdsOutOfStock.isEmpty()) {
order.setStatus(OrderStatus.ItemsInStock);
shippingService.startPackagingOrder(order);
emailService.send(generateOrderOrderItemsInStockEmail(order));
} else {
order.setStatus(OrderStatus.NotAllItemsInStock);
emailService.send(generateOrderItemsNotInStockEmail(order, productIdsOutOfStock));
executeMethod(OrderService::checkOrderInventoryStatus, Period.ofDays(1));
}
}
@jeppec
What about
race conditions?
@jeppec
public class OrderService {
public void save(Order order) {
orderRepository.add(order);
List<ProductId> productIdsOutOfStock = inventoryService.checkProductStockStatus(
order.orderLines.toMap(OrderLine::productId, OrderLine::quantity));
if (productIdsOutOfStock.isEmpty()) {
order.setStatus(OrderStatus.ItemsInStock);
shippingService.startPackagingOrder(order);
emailService.send(generateOrderOrderItemsInStockEmail(order));
} else {
order.setStatus(OrderStatus.NotAllItemsInStock);
emailService.send(generateOrderItemsNotInStockEmail(order, productIdsOutOfStock));
executeMethod(OrderService::checkOrderInventoryStatus, Period.ofDays(1));
}
}
@jeppec
public class OrderService {
public void save(Order order) {
orderRepository.add(order);
List<ProductId> productIdsOutOfStock = inventoryService.reserveProductsForOrder(order.orderId,
order.orderLines.toMap(OrderLine::productId, OrderLine::quantity));
if (productIdsOutOfStock.isEmpty()) {
order.setStatus(OrderStatus.ItemsInStock);
shippingService.startPackagingOrder(order);
emailService.send(generateOrderOrderItemsInStockEmail(order));
} else {
order.setStatus(OrderStatus.NotAllItemsInStock);
emailService.send(generateOrderItemsNotInStockEmail(order, productIdsOutOfStock));
executeMethod(OrderService::checkOrderInventoryStatus, Period.ofDays(1));
}
}
Introduces an additional side effect
@jeppec
Essential complexity of 2 way integration
Inventory
Service
Order
Service
Shipping
Service
UI
Start-
Packaging
Save-Order
Order:Save-Order()
call Inventory:Reserve-Products()
call Shipping:Start-Packaging()
commit()
Reserve-
Products
Local transaction between the 3
“Services”
@jeppec
Let’s (micro)service’ify this
@jeppec
Accidental complexity from distributed service integration
Inventory
Service
Order
Service
Shipping
Service
UI
Start-
Packaging
Save-Order
Reserve-
Products
Local transaction between 2 local
“Services”Remote call
@jeppec
Remote Call?
RPC/REST/SOAP/…
@jeppec
What’s the challenge with
using a Pull model between
distributed components?
@jeppec
@jeppec
Synchronous calls lower our tolerance for faults
• When you get an IO error
• When servers crash or restarts
• When databases are down
• When deadlocks occurs in our databases
• Do you retry?
With synchronous style Service interaction we can loose business data if there’s no automatic retry
Or we risk creating data more than once if the operation isn’t idempotent*
Client Server
Duplicated Response
Duplicated Request
Processing
Response
Request Processing
The same message can be
processed more than once
*Idempotence describes the quality of an operation
in which result and state does not change if the
operation is performed more than 1 time
@jeppec
Idempotence
Don’t press the button twice!
@jeppec
Ensuring
consistency
is much harder
@jeppec
Sales system
Sale
Delivery
system Deliveries
Customer/CRM
system Customer
SAP Bookkeeping
Complete
Purchase
Transaction
Coordinator
Transactional
Resource
Prepare
Phase
Commit
Phase
2 Phase Commit
@jeppec
What’s wrong with distributed transactions?
• Transactions lock resources while active
• Services are autonomous
• Can’t be expected to finish within a certain time interval
• Locking keeps other transactions from completing their job
• Locking doesn’t scale
• X Phase Commit is fragile by design
@jeppec
Using the pull model
we’re prone to
cascading failure
@jeppec
Order:Save-Order()
call Inventory:Reserve-Products()
call Shipping:Start-Packaging()
if (Shipping:Call-Failed:Too-Busy?)
Wait-A-While()
call Shipping:Start-Packaging()
if (Shipping:Call-Failed:Too-Busy?)
Wait-A-Little-While-Longer()
call Shipping:Start-Packaging()
if (Shipping:Call-Failed:IO-Error?)
Save-We-Need-Check-If-Call-Shipping-Succeded-After-All
AND We-Need-To-Retry call Order:Save-Order and call Inventory:Reserve-Products
AND Tell-Customer-That-This-Operation-Perhaps-Went-Well
if (Shipping:Call-Went-Well?)
commit()
Accidental complexity from distributed service integration
Inventory
Service
Order
Service
Shipping
Service
UI
Start-
Packaging
Save-Order
Reserve-
Products
Local transaction between 2
Components
@jeppec
“A distributed system is one
where a machine I’ve never heard
of can cause my program to fail”
— Leslie Lamport
@jeppec
Service autonomy
Order Inventory
Shipping
Retail System
Shipping
Order Inventory
Retail System
Slow/unreliable network
Different SLA
Slow system
@jeppec
Availability goes down
(without additional instances of each service)
Combined availability: 97%
@jeppec
Services != Decoupling
@jeppec
But surely RPC is the only way
to do this?
@jeppec
We need to switch from a pull
to a push model
Which means we need to change our approach
slightly but profoundly
@jeppec
Most applications are built with CRUD as the main
paradigm
Intention gets lost
@jeppec
We need to shift focus from pure data
towards intent and process automation
This means a change from CRUD style application design, where the
process was implicit and stored in the minds of the users
First I need to
enter the
employee in
this screen
Then I need to press
a button in the user
system so they’re
properly created
And the I need to
add their access
card to this screen
and press Activate
@jeppec
We need to capture User Intent at the UI
CRUD style
Task based style
Intent
@jeppec
Task-based/Inductive UI
• Traditional CRUD UI is what I would call a WHAT UI
• Task based UI’s focuses on HOW the user wants to use the
application
• Guides users through the work process
• The UI becomes an intrinsic part of the design
• The UI design directly affects our commands and thereby our
transactional boundaries
@jeppec
Capturing intent in the form of a Command
A Command is prescriptive of what should happen, and its primary goal is to capture USER
INTENT
A Command
supports a single usecase and
targets a single business object
within a single Transaction
Commands always carry a name in its imperative form:
• AcceptOrder
• ShipOrder
• CancelOrder
• ReimburseCustomer
• Etc.
“A command describes a Task that you want someone else to carry out
for you and where the recipient can choose to reject the Command”
@jeppec
Let’s capture the intent of the customer
public class OrderService {
public void handle(AcceptOrder cmd) {
orderRepository.add(new Order(cmd.orderId,
cmd.orderLines));
????
}
@jeppec
How do we get the
ball moving now that we can’t
use RPC?
@jeppec
Life Beyond Distributed Transactions
by Pat Helland
1. How do we split our data
2. How do we identify our data
3. How do we communicate between our services
@jeppec
1. How do we split our data
Data must be collected in pieces called aggregates.
These aggregates should be limited in size (but not smaller), so that,
after a transaction they are consistent.
Rule of thumb:
One transaction involves only one aggregate.
@jeppec
Domain Driven Design
The term Aggregate comes from DDD
@jeppec
Aggregates
Invoice
InvoiceLine
*
Account *
What:
• Cluster coherent Entities and Value Objects, with
complex associations into Aggregates with well
defined boundaries.
• Choose one entity to be root and control access to
objects inside the boundary through the root.
Motivation:
Control invariants and consistency through the aggregate root.
Ensuring consistency & transactional boundaries for Distributed scenarios!
Root
*
*
@jeppec
2. How do we identify our data
According to Pat Helland we need to be able to uniquely identify each
Aggregate using an ID.
• This ID will usually a UUID/GUID
{21EC2020-3AEA-4069-A2DD-08002B30309D}
2122 (approximately 5.3×1036) combinations
@jeppec
Aggregates refer to each other by ID
they NEVER use memory pointers, join tables or remote calls
@jeppec
Services/Bounded Contexts and Aggregates
Order
Product
Customer
customerId
…
Order
orderId
customerId
…
OrderLine
orderId
productId
quantity
price
ProductCategory
productCategoryId
…
Product
productId
productCategoryId
name
tag
...
@jeppec
3. How do we communicate between our services
What do we do when our process involves more than
one aggregate and therefore likely more than one
service?
@jeppec
Synchronous calls are the crystal meth of programming
At first you make good progress but then the sheer horror
becomes evident when you realise the scalability limitations
and how the brittleness holds back both performance and
development flexibility. By then it is too late to save.
http://www.infoq.com/news/2014/10/thompson-reactive-manifesto-2
We need the reactive properties and then apply protocols
for the message interactions. Without considering the
protocols of interaction this world of micro-services will
become a coordination nightmare.
Martin Thompson
@jeppec
Reactive?
@jeppec
Coupling matrix*
* Modified version of Ian Robinson’s matrix: http://iansrobinson.com/2009/04/27/temporal-and-behavioural-coupling/
Behavioral
coupling
Temporal
coupling
Low High
Low
High
Reactive/
Event oriented
Command oriented
Emergency services Distributed 3 layer
@jeppec
We need to change focus from short
technical transactions
To long running business transactions supporting
business processes
@jeppec
Using Business Events to drive Business Processes
Order Service
Shipping
Billing
Sales
Customers
MessageChannel
Online Ordering System
Web Shop
(Composite UI)
Inventory Service
Shipping Service
Order
Accepted
AcceptOrder
The sales
fulfillment
processing can
now begin…
@jeppec
Events
An Event is non-prescriptive of what should happen in other parts of the system.
An event will typically be published to multiple consumers/subscribers:
• The publisher of the event does not know who the subscribers are
• And the publisher doesn’t know what the subscribers intend to do with the event
Events always carry a name in its past-tense form:
OrderWasAccepted
OrderHasShipped
CustomerWasReimbursed
“An Event describes something that HAS happened”
@jeppec
Push model
• Event based integration follows a push based model that breaks
temporal coupling and avoids cascading failures
• Events can be exchanged between services over a message channel
(that can be implemented using a push or pull protocol)
Sender
Address Changed Event
Receiver
Address Changed Event
Channel
Asynchronous Communication – A.k.a. Messaging
@jeppec
Smart pipes and “dumb” endpoints – Push protocol
Service X
Publish
Topic
Data and flow direction
Message infrastructure
(e.g. Kafka, RabbitMQ, QBus)
Service Z
Subscribe
Service Y
Subscribe
Service M
Subscribe
@jeppec
Service X
Publish
Service Z
Consume
Service Y
Consume
Service M
Consume
Atom File based Feed
generator
Oldest
Feed
Older
Feed
Old
Feed
Feed
Head Previous feed link
HTTPEndpoint
Next feed link
Next feed link
Previous feed link
HTTP Reverse
Proxy
HTTP Reverse
Proxy
Cache
Cache
Atom Pub Feed
as a JSON/XML
file
Dumb pipes and smart endpoints (Pull Protocol)
Data and flow direction
@jeppec
Business Event as XML Message
<OrderWasAccepted>
<CustomerId>50D1F244-ABBC-4EC7-BDCA-E4934C124A89</CustomerId>
<OrderId>C199322A-01F1-4E56-918E-7A63529F8FA3</OrderId>
<ShippingAddress> ... </ShippingAddress>
<BillingAddress> ... </BillingAddress>
<Items>
<Item ProductId="4CD22C4B-600C-4477-B5BF-48ABDEE4DA61" Amount="100"
AmountUnit="Pieces" UnitPrice="100,10" UnitCurrency="EUR"/>
<Item ProductId="56E6BD19-660C-464A-9120-100DAF579855" Amount="10"
AmountUnit="Litres" UnitPrice="56,95" UnitCurrency="CHF"/>
</Items>
</OrderWasAccepted>
@jeppec
Business Event as JSON Message
{
EventType: "OrderWasAccepted",
CustomerId: "50D1F244-ABBC-4EC7-BDCA-E4934C124A89",
OrderId: "C199322A-01F1-4E56-918E-7A63529F8FA3",
ShippingAddress: { ... }
BillingAddress: { ... }
Items: [
{
ProductId: "4CD22C4B-600C-4477-B5BF-48ABDEE4DA61",
Amount: "100",
AmountUnit: "Pieces",
UnitPrice: "100,10",
UnitCurrency: "EUR"
},
{
ProductId: "56E6BD19-660C-464A-9120-100DAF579855",
Amount: "10",
AmountUnit: "Litres",
UnitPrice: "56,95",
UnitCurrency: "CHF"
}
]
}
@jeppec
Different uses for Events
• Master data management and Data duplication
• Data replication / migration
• Notification
• Service autonomy and Loosely coupled workflows/business processes
across Services
• UI component integration
@jeppec
Master data management
@jeppec
System A
System
B
System
C
System
D
4 systems with shared data and no clear master for data
@jeppec
Login
Contact
Information
Memberships
CustomerMaster
System A
System
B
System
C
System
D
New solution
@jeppec
System A
Update Customer
Contact Info
Update
Customer
ContactInfo
Process
”UpdateCustomerContactInfo”
command
Event Publisher
”CustomerContactInfoUpdated” Event
Customer View
Customer
local/cached replica
System D
BI/And other parties
System B
Customer Master
@jeppec
Event channel based migration
New UI Old UI
Command Action
SQL
D
E
<<Read replica>>
C
Publishes Events
Event Publisher Channel
SQL
A
B
C
@jeppec
Example of Event based notification
TrainPositionChanged
TrainStopped
TrainStarted
…
Every 5 ms.
Subscriber A
Subscriber B
Subscriber C
@jeppec
Business Processes
@jeppec
Eventual consistency
• Consistency is with each Service
• Eventual consistency is between Services
• Like in the real world
Sales Invoicing
Inventory Shipping
Order
Accepted
Invoice Customer
Checks Inventory for availability Books truck driver
Order
Packaged
Fetch Package from Inventory
Customer
Invoiced
@jeppec
Important!
Figure out who owns the process
@jeppec
Gain competitive advantage
From vertical integration
@jeppec
Choreographed Event Driven Processes
Sales Service
Order
Accepted
Billing Service
Order Fulfilment
(Saga/
Process-Manager)
Shipping Service
Online Ordering System
MessageChannel(e.g.aTopic)
Order
Accepted
Order
Accepted
Customer
Billed
Customer
Billed
Order
Approved
Order
Approved
Works as a Finite
State Machine
(WorkFlow)
handling the life
cycle of Shipping and
thereby forms a very
central new
Aggregate in the
System
@jeppec
Process Managers
• Process Managers are essential to the coordination and
monitoring of long running business
processes/transactions
• They work as a Finite State Machines (WorkFlow) which
handling the life cycle of Process (e.g. Shipping an Order)
and thereby forms a very central new Aggregate in the
System
• They can include manual steps/person intervention
• Sometimes these Process Managers belong naturally
within a specific Business capability and other times they
are truly and thing by themselves and often form new
business capabilities that way
Many companies derive their competitive advantages from their Processes.
A Process Manager allows you coordinate Business Processes on the basis of Events
@jeppec
Back to our example
@jeppec
Choreographed Event Driven Processes
Order Service
Order
Accepted
Inventory Service
Shipping Service
Online Ordering System
MessageChannel(e.g.aTopic)
Order
Accepted
Inventory
Products
Reserved
Inventory
Products
Reserved
Order Ready
For
Shipping
Order
Ready For
Shipping
@jeppec
Accept Order flow
public class OrderService {
public void handle(AcceptOrder cmd) {
orderRepository.add(new Order(cmd.orderId,
cmd.orderLines));
publish(new OrderAccepted(
cmd.orderId,
cmd.orderLines.toMap(OrderLine::productId,
OrderLine::quantity))
);
}
@jeppec
Inventory flow
public class InventoryService {
public void on(OrderAccepted e) {
List<ProductId> productIdsOutOfStock = reserveProductsForOrder(e.orderId,
e.productsToReserve);
if (productIdsOutOfStock.isEmpty()) {
publish(new InventoryProductsReserved(e.orderId, e.productsToReserve));
} else {
publish(new InventoryProductsOutOfStock(e.orderId, e.productsToReserve,
productIdsOutOfStock));
}
}
@jeppec
Message Handling and Idempotence
public class OrderShippingProcess {
private void on(OrderPaid orderPaid, ProductsReserved productsReserved) {
ShippingDetails shippingDetails = getShippingDetailsForOrder(orderPaid.orderId);
….
printShippingLabel(orderPaid.orderId, shippingDetails.address);
}
…
} Must also be idempotent
@jeppec
There are only two hard
problems in distributed
systems
2. Exactly Once Delivery
1. Guaranteed Order of Messages
2. Exactly Once Delivery
@mathiasverraes
@jeppec
Things are not quite the same
In a distributed systems the order in which messages arrive is not
guaranteed
In a distributed systems message delivery can and will fail!
Messages can depending on guarantees be delivered:
• At Most Once – If you don’t care about loosing messages
• Page visits
• Ad views
• Other types of notifications
• Exactly Once
• Not really possible
• At Least Once
• For everything else – which is why:
Everything that can handle messages must be built with idempotency in mind!
@jeppec
Event coordination
• Do NOT copy data from incoming event to outgoing event – instead use
Event coordination from the next slide
Service C Event C
Data:
X
Data: Y
Data:
C, Y
Service D
This form of data copying from incoming
event to outgoing event is prohibited
@jeppec
Event coordination continued
• Rule: If Service D also needs data from Event B, then Service D should
also listen for Event B instead of having Service C copy data from Event
B to Event C
Service C Event C
Data:
X
Data: Y
Data:
C
Service
D
Data: Y
@jeppec
What should our Events look like?
• Keep Events Small
• Only include relevant metadata (such as sequence) and business data
• If possible, don’t include unnecessary id’s for aggregates in other services
• Think Inverse relationships based on what feels most natural
• Order doesn’t need to know the Shipping Id, but Shipping can know the Order Id
• Anchor Events to Time
• Include information about how long you can trust the Event’s change
• E.g. a price is valid until 8pm tomorrow night
• Reveal the intention and time anchoring as part of the Events name
@jeppec
Internal vs External Events
{
EventType: ”OrderWasPaid",
CustomerId: "50D1F244-ABBC-4EC7-BDCA-E4934C124A89",
OrderId: "C199322A-01F1-4E56-918E-7A63529F8FA3",
Amount: …..
}
Internal Event:
{
EventType: "OrderWasPaid",
OrderId: "C199322A-01F1-4E56-918E-7A63529F8FA3"
}
External Event:
@jeppec
Avoid using Events for generic services
When ever a new Service is introduced
the Generic Service (X) needs to be changed.
This creates an unnecessary degree of coupling
Service
A
Service
B
Service
C
Service X
Service
D
Event X
@jeppec
Use Commands for generic services
Instead of having Service X listen for MANY different events, let
Service X expose a command interface that other services can
use instead
Service
A
Service
B
Service
C
Service X
Service
D
Event X
@jeppec
When to prefer a Pull based model?
• You want to have Authority (as opposed to Autonomy)
• Such as with a bank account
• GDPR compliance
• So sensitive data is only stored in one place (avoid data duplication)
• Orchestration of processes
• Sometimes events result in too much ceremony
• You have large amounts of data and your queries only involve a small set of
this data
• Example a Google search
• Most UI to backend interactions
• Loading data from the backend
• Pressing a button to send a Query or issue a Command
@jeppec
How does shipping know
where to ship items to?
@jeppec
Check out process
@jeppec
Order Id
• Customer/customer-id
@jeppec
Order Id
• Customer/customer-id
Linked to Order Id:
• Order Delivery address
• Order Shipping method
Linked to Order Id:
• Order shipping price
@jeppec 91
Order
OrderId
Total
DeliveryAddress
Status
…
Decomposing the domain
Order
OrderId
Total
Status
…
ShippingDetails
OrderId
DeliveryAddress
@jeppec
Composite page example
Page Context:
{id: ISBN-10 0-321-83457-7 }
Images
Books
Reviews
Pricing
Inventory
OthersAlsoBought
Pricing
Reviews
Books
Images
Books
@jeppec
Service
Service - 1
Service - 2Service - 2
Service - 3
Service - 3Service - 4
Broker
Broker
(Kafka,
RabbitMQ,
JMS)
Service - 1Service - 1
Service - 1
Service - 2
Service - 2
Service - 3
Service - 3
Service - 4
Service - 4
Service - 4
@jeppec
Service
Service - 1
Service - 1Service - 1
Service - 1
Service - 2
Service - 2
Service - 2
Service - 2
Service - 3
Service - 3
Service - 3
Service - 3
Service - 4
Service - 4
Service - 4
Service - 4
QBus
@jeppec
pricing_engine_ac
(deployed on 10.25.26.102)
pricing_engine_ac
(deployed on 10.25.26.101)
Bus Bus
Bus Bus
inventory_ac
(deployed on 10.25.26.104)
inventory_ac
(deployed on 10.25.26.103)
Federated Bus
@jeppec
Topics
Bus features
• Decouples publisher from subscribers
• Provides temporal decoupling
• If a subscriber is unavailable it will receive its messages when it comes
online
Service - 4
Service - 1
Service - 3
@jeppec
Topics
CreateOrder
Sales_Service:Orders_Ac
Webshop Application
Customer_Service:Some_Ac
OrderCreated
OrderCreatedEvent
Publish
CreateSomeRelatedAggregate
Sales_Service:OrderEvents
<<Topic>>
OrderCreatedEvent
@jeppec
Topics
Bus features
But how do we handle:
• Coding errors in Subscribers?
• New Subscribers that didn’t exist when the events were originally
published?
Service - 4
Service - 1
Service - 3
@jeppec
@jeppec
1. Realization
Commands and Queries
support very different usecases
@jeppec
A single model cannot be
appropriate for reporting,
searching and transactional
behavior
Greg Young
@jeppec
The Triangular Architecture
Task based
UI
Write
ModelRead ModelRead Model
Read
Models
@jeppec
Commands & Events
Commands mutate Write model state
which results in
one or more Events being published.
Command Event(s)
AcceptOrder OrderAccepted
ShipOrder OrderShipped
AddComment CommentAdded
QuarantineReview ReviewQuarantined
UnquarantineReview ReviewUnquarantined
@jeppec
The circle is completing
@jeppec
We can use Domain Events to build our
View/Query models
@jeppec
Read model
Read model
Commands, Events and Query Models
Events
UI
Write modelView models
”AcceptOrder”
command
”OrderAccepted”
event
”Find all Accepted Orders”
Query
Commands are Imperative: DoStuff
Events are Past tense: StuffDone
@jeppec
CQRS Building blocks
Client
Commands
Command
Bus
Sends
Command
Handlers
Modify
Repositories
Read Write
Data
store
Event
Bus
Event Handlers
Events
Read store
Query HandlersQuery Results
Queries
Events
Domain
@jeppec
Event Sourcing
Write-Model/Aggregates track their own Domain Events
and derive state from them
Time
07:39
Time
07:40
Time
07:41
Time
07:45
Time
07:46
Time
07:50
CRUD
There’s no reason to delete data or update data.
We only need to append and read Events from our Event Store
@jeppec
Event Replaying
Type Aggregate
Identifier
Sequence
Number
Timestamp Event
Identifier
EventType SerializedEvent
Order 14237 0 2014-01-06 7:39 {Guid-1} OrderCreated <serialized event>…
Order 14237 1 2014-01-06 7:40 {Guid-2} ProductAdded <serialized event>…
Order 14237 2 2014-01-06 7:41 {Guid-3} ProductAdded <serialized event>…
Order 14237 3 2014-01-06 7:45 {Guid-4} ProductRemoved <serialized event>…
Order 14237 4 2014-01-06 7:46 {Guid-5} ProductAdded <serialized event>…
Order 14237 5 2014-01-06 7:50 {Guid-6} OrderAccepted <serialized event>…
Order
Accepted: true
Orderline
Orderline
@jeppec
Full CQRS with EventSourcing
UI Domain
Event
Store
Commands – Change data
Commands Events
SQL DB Document DB Graph DB
UI Data
Queries – Ask for data
Events
Query Build
Our single source
of truth
@jeppec
And we can use the
EventStore to support event
replays for new subscribers
@jeppec
Client handled subscriptions
• Highly resilient pattern for an Event Driven Architecture that’s backed by
Event-Sourced services
• In this model the publisher of the Events is responsible for the durability of
all its Events, typically to an EventStore/EventLog.
• Each client (subscriber) maintains durable information of the last event it has
received from each publisher.
• When ever the client starts up it makes a subscription to the publisher
where it states from which point in time it wants events published/streamed
to it.
• This effectively means that publisher can remain simple and the client
(subscriber) can remain simple and we don’t need additional sophisticated
broker infrastructure such as Kafka+ZooKeeper.
@jeppec
Client handled subscriptions
Publisher
Subscriber A
Local storage
EventStore
Subscriber B
Local storage
Topic
Subscription
Topic
Subscription
TopicSubscriptionHandler
TopicSubscriptionHandler
EventEvent
Event Event
EventBus
Event
Event
Distributed Event Bus,
which ensures that
live events published
on an AC node in the
cluster can be seen
by all AC’s of the
same type
Singe Instance
Subscriber, which
ensures that only
one instance of
Subscriber B has
an active
subscription(s).
Other instances of
the same
subscriber are
hot-standby
<<Topic Subscriber>>
Customer_Service:Some_Ac:OrderEvents
<<Topic Publisher>>
Sales_Service:OrderEvents
@jeppec
Topics
Bus features
Service - 4
Service - 1
Service - 3
bus.registerReplayableTopicPublisher(InternalPricingEvents.TOPIC_NAME,
replayFromAggregate(Pricing.class)
.dispatchAggregateEventsOfType(
InternalPricingEvents.class
)
);
bus.subscribeTopic(SERVICE_AC_ID.topicSubscriber(”Pricing"),
InternalPricingEvents.TOPIC_NAME,
new PricingTopicSubscription(bus));
@jeppec
Topics
public class PricingTopicSubscription extends BusMessageHandlerDelegator {
@BusMessagePayloadHandler
private void on(PrincingChanged e, BusMessage<PricingChanged> msg) {
…
}
…
}
@jeppec
Topics
Bus features
Features:
• The Bus provides automatic and durable handling of Redelivery in case of message handling failure
through a Redelivery Policy
• Exponential Back-off
• Max retries
• Dead letter/Error Queue
• Support for resubscription at any point in the timeline of an Event Stream
• Automatically tracking of resubscription points - aka. resubscribe at last tracked point
Service - 4
Service - 1
Service - 3
@jeppec
Can’t we just use Kafka?
@jeppec
With Kafka we still need smart
endpoints
@jeppec
Requires a lot of work
@jeppec
Bus features
Features:
• Support for sending a message to a single consumer
• Default pattern is Competing Consumers
• The bus provides durability for all messages sent on a Queue
• The Bus provider automatic and durable handling of Redelivery in case of message handling failure
through a Redelivery Policy
• Exponential Backoff
• Max retries
• Dead letter/Error Queue
Durable Queues
@jeppec
Can’t we just use Kafka?
@jeppec
Bus features
Notifications:
• Durable notifications with failover support
• bus.notify(notificationQueue, notificationMessage)
Notifications
Distributed
Broadcast
Broadcast:
• Broadcast a Message to all Services in the cluster
• Broadcast a Message to a UI client (all, per user, per privilege)
@jeppec
Bus features
Single Instance Task:
• Ensures that only one Active instance of a Task is active in the cluster at one time
• Other tasks of the same type are in hot standby
• Used to e.g. group multiple subscribers, to ensure that all subscribers are either all
active or standby.
• Used by our ViewRepositories
Distributed
SingleInstanceTask
bus.createClusterSingleInstanceTask(”MyTask",
new MyTask ()); // Where MyTask implements Lifecycle
@jeppec
Bus features
Process Manager
• Defines durable business processes
as a flow of Events
Sagas
Process Manager
Sales Service
Order Accepted
Billing Service
Order Fulfilment
(Saga/
Process-Manager)
Shipping Service
MessageChannel(e.g.aTopic)
Order Accepted
Order Accepted
Customer Billed
Customer Billed
Order Approved
Order Approved
@jeppec
Application features
Workflow Manager:
• Defines the Tasks that required human intervention, such as:
• Approvals (e.g. Contract approval)
• Assistance/Help with a business problem
• Incident handling (e.g. a technical problem identified by a developer)
• Authorization (e.g. request manager approval)
• Reminders
• Common tasks supported: Claiming Tasks, Escalating Tasks, Completing Tasks
Workflow Manager
@jeppec
Event Monitoring
• One of the challenges with have Event based systems is to keep track
of where events are in the flow
• Why isn’t this system doing this?
• Did events go into an Error Queue?
• How can we reprocess them?
• Or why isn’t this happening?
• In general it’s the same issues we see with asynchronous systems and
integrations in general.
• The good thing about using Events is that they carry semantics and are not RPC
in hiding
@jeppec
Event Monitoring
Command, Document and Event messages all contain the following
data:
• Timestamp
• Unique message Id
• Correlation Id
• Originating system (IP address, name, etc.)
• …
Event messages also need to describe the order in which the event
occurred. This can be implemented in many ways including:
• Ordering sequence number
• Event vectors
• Vector clocks
• Timestamp
• Etc.
@jeppec
Event Monitoring
• We use the correlation id to be able to later correlate log
messages from different services
@jeppec
Example monitoring of Processes
Thanks :)
Blog: https://cramonblog.wordpress.com/
Homepage: http://cloudcreate.dk/
Twitter: @jeppec

More Related Content

What's hot

REST != WebAPI
REST != WebAPIREST != WebAPI
REST != WebAPI
Dan (Danut) Prisacaru
 
Effective Akka v2.0 - Jamie Allen
Effective Akka v2.0 - Jamie AllenEffective Akka v2.0 - Jamie Allen
Effective Akka v2.0 - Jamie Allen
JAXLondon_Conference
 
SOA Pattern Event Driven Messaging
SOA Pattern Event Driven MessagingSOA Pattern Event Driven Messaging
SOA Pattern Event Driven MessagingWSO2
 
The "Why", "What" and "How" of Microservices
The "Why", "What" and "How" of Microservices The "Why", "What" and "How" of Microservices
The "Why", "What" and "How" of Microservices
INPAY
 
SOA vs EDA
SOA vs EDASOA vs EDA
Event-Driven Service-oriented Architecture (EDSOA)
Event-Driven Service-oriented Architecture (EDSOA)Event-Driven Service-oriented Architecture (EDSOA)
Event-Driven Service-oriented Architecture (EDSOA)
Attune Infocom Pvt Ltd
 
Architecting for Change: An Agile Approach
Architecting for Change: An Agile ApproachArchitecting for Change: An Agile Approach
Architecting for Change: An Agile Approach
Ben Stopford
 
CQRS and what it means for your architecture
CQRS and what it means for your architectureCQRS and what it means for your architecture
CQRS and what it means for your architecture
Richard Banks
 
Event sourcing
Event sourcingEvent sourcing
Event sourcing
Touraj Ebrahimi
 
Event Driven Architecture
Event Driven ArchitectureEvent Driven Architecture
Event Driven Architecture
Chris Patterson
 
EventDrivenArchitecture
EventDrivenArchitectureEventDrivenArchitecture
EventDrivenArchitectureHiroshi Ono
 
Walmart pagespeed-slide
Walmart pagespeed-slideWalmart pagespeed-slide
Walmart pagespeed-slide
Bitsytask
 
JavaScript Frameworks and Java EE – A Great Match
JavaScript Frameworks and Java EE – A Great MatchJavaScript Frameworks and Java EE – A Great Match
JavaScript Frameworks and Java EE – A Great Match
Reza Rahman
 
SOA with Zend Framework
SOA with Zend FrameworkSOA with Zend Framework
SOA with Zend Framework
Mike Willbanks
 
Spring One DC 2012: Building For Performance with Spring Integration & Spring...
Spring One DC 2012: Building For Performance with Spring Integration & Spring...Spring One DC 2012: Building For Performance with Spring Integration & Spring...
Spring One DC 2012: Building For Performance with Spring Integration & Spring...
andrewelmore
 

What's hot (16)

REST != WebAPI
REST != WebAPIREST != WebAPI
REST != WebAPI
 
Effective Akka v2.0 - Jamie Allen
Effective Akka v2.0 - Jamie AllenEffective Akka v2.0 - Jamie Allen
Effective Akka v2.0 - Jamie Allen
 
SOA Pattern Event Driven Messaging
SOA Pattern Event Driven MessagingSOA Pattern Event Driven Messaging
SOA Pattern Event Driven Messaging
 
The "Why", "What" and "How" of Microservices
The "Why", "What" and "How" of Microservices The "Why", "What" and "How" of Microservices
The "Why", "What" and "How" of Microservices
 
SOA vs EDA
SOA vs EDASOA vs EDA
SOA vs EDA
 
Event-Driven Service-oriented Architecture (EDSOA)
Event-Driven Service-oriented Architecture (EDSOA)Event-Driven Service-oriented Architecture (EDSOA)
Event-Driven Service-oriented Architecture (EDSOA)
 
Cqrs api v2
Cqrs api v2Cqrs api v2
Cqrs api v2
 
Architecting for Change: An Agile Approach
Architecting for Change: An Agile ApproachArchitecting for Change: An Agile Approach
Architecting for Change: An Agile Approach
 
CQRS and what it means for your architecture
CQRS and what it means for your architectureCQRS and what it means for your architecture
CQRS and what it means for your architecture
 
Event sourcing
Event sourcingEvent sourcing
Event sourcing
 
Event Driven Architecture
Event Driven ArchitectureEvent Driven Architecture
Event Driven Architecture
 
EventDrivenArchitecture
EventDrivenArchitectureEventDrivenArchitecture
EventDrivenArchitecture
 
Walmart pagespeed-slide
Walmart pagespeed-slideWalmart pagespeed-slide
Walmart pagespeed-slide
 
JavaScript Frameworks and Java EE – A Great Match
JavaScript Frameworks and Java EE – A Great MatchJavaScript Frameworks and Java EE – A Great Match
JavaScript Frameworks and Java EE – A Great Match
 
SOA with Zend Framework
SOA with Zend FrameworkSOA with Zend Framework
SOA with Zend Framework
 
Spring One DC 2012: Building For Performance with Spring Integration & Spring...
Spring One DC 2012: Building For Performance with Spring Integration & Spring...Spring One DC 2012: Building For Performance with Spring Integration & Spring...
Spring One DC 2012: Building For Performance with Spring Integration & Spring...
 

Similar to Should you be using an event driven architecture?

Updated: Should you be using an Event Driven Architecture
Updated: Should you be using an Event Driven ArchitectureUpdated: Should you be using an Event Driven Architecture
Updated: Should you be using an Event Driven Architecture
Jeppe Cramon
 
Building React Applications with Redux
Building React Applications with ReduxBuilding React Applications with Redux
Building React Applications with Redux
FITC
 
Data Warehouse 2.0: Master Techniques for EPM Guys (Powered by ODI)
Data Warehouse 2.0: Master Techniques for EPM Guys (Powered by ODI)Data Warehouse 2.0: Master Techniques for EPM Guys (Powered by ODI)
Data Warehouse 2.0: Master Techniques for EPM Guys (Powered by ODI)
Rodrigo Radtke de Souza
 
...and thus your forms automagically disappeared
...and thus your forms automagically disappeared...and thus your forms automagically disappeared
...and thus your forms automagically disappearedLuc Bors
 
What SQL should actually be...
What SQL should actually be...What SQL should actually be...
What SQL should actually be...Open Academy
 
Grails Services
Grails ServicesGrails Services
Grails Services
NexThoughts Technologies
 
Enough Blame for System Performance Issues
Enough Blame for System Performance IssuesEnough Blame for System Performance Issues
Enough Blame for System Performance IssuesMahesh Vallampati
 
Sharing our best secrets: Design a distributed system from scratch
Sharing our best secrets: Design a distributed system from scratchSharing our best secrets: Design a distributed system from scratch
Sharing our best secrets: Design a distributed system from scratch
Adelina Simion
 
Systems Monitoring with Prometheus (Devops Ireland April 2015)
Systems Monitoring with Prometheus (Devops Ireland April 2015)Systems Monitoring with Prometheus (Devops Ireland April 2015)
Systems Monitoring with Prometheus (Devops Ireland April 2015)
Brian Brazil
 
JavaOne 2015: Top Performance Patterns Deep Dive
JavaOne 2015: Top Performance Patterns Deep DiveJavaOne 2015: Top Performance Patterns Deep Dive
JavaOne 2015: Top Performance Patterns Deep Dive
Andreas Grabner
 
B.tech admission in india
B.tech admission in indiaB.tech admission in india
B.tech admission in india
Edhole.com
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - Talk
Matthias Noback
 
PlayStation and Lucene - Indexing 1M documents per second: Presented by Alexa...
PlayStation and Lucene - Indexing 1M documents per second: Presented by Alexa...PlayStation and Lucene - Indexing 1M documents per second: Presented by Alexa...
PlayStation and Lucene - Indexing 1M documents per second: Presented by Alexa...
Lucidworks
 
OOSE UNIT-1.pdf
OOSE UNIT-1.pdfOOSE UNIT-1.pdf
OOSE UNIT-1.pdf
KarumuriJayasri
 
BPCS Infor ERP LX Implementation Evaluation Q4 2007
BPCS Infor ERP LX Implementation Evaluation Q4 2007BPCS Infor ERP LX Implementation Evaluation Q4 2007
BPCS Infor ERP LX Implementation Evaluation Q4 2007
Dedy Sofyan
 
P _n___l_accounting_website
P  _n___l_accounting_websiteP  _n___l_accounting_website
P _n___l_accounting_website
Ashish Sharma
 
Asynchronous Apex Salesforce World Tour Paris 2015
Asynchronous Apex Salesforce World Tour Paris 2015Asynchronous Apex Salesforce World Tour Paris 2015
Asynchronous Apex Salesforce World Tour Paris 2015
Samuel De Rycke
 
AtlasCamp 2015: Damn you Facebook - Raising the bar in SaaS
AtlasCamp 2015: Damn you Facebook - Raising the bar in SaaSAtlasCamp 2015: Damn you Facebook - Raising the bar in SaaS
AtlasCamp 2015: Damn you Facebook - Raising the bar in SaaS
Atlassian
 
SBJUG - Building Beautiful Batch Jobs
SBJUG - Building Beautiful Batch JobsSBJUG - Building Beautiful Batch Jobs
SBJUG - Building Beautiful Batch Jobs
stephenbhadran
 
Sea of Data
Sea of DataSea of Data

Similar to Should you be using an event driven architecture? (20)

Updated: Should you be using an Event Driven Architecture
Updated: Should you be using an Event Driven ArchitectureUpdated: Should you be using an Event Driven Architecture
Updated: Should you be using an Event Driven Architecture
 
Building React Applications with Redux
Building React Applications with ReduxBuilding React Applications with Redux
Building React Applications with Redux
 
Data Warehouse 2.0: Master Techniques for EPM Guys (Powered by ODI)
Data Warehouse 2.0: Master Techniques for EPM Guys (Powered by ODI)Data Warehouse 2.0: Master Techniques for EPM Guys (Powered by ODI)
Data Warehouse 2.0: Master Techniques for EPM Guys (Powered by ODI)
 
...and thus your forms automagically disappeared
...and thus your forms automagically disappeared...and thus your forms automagically disappeared
...and thus your forms automagically disappeared
 
What SQL should actually be...
What SQL should actually be...What SQL should actually be...
What SQL should actually be...
 
Grails Services
Grails ServicesGrails Services
Grails Services
 
Enough Blame for System Performance Issues
Enough Blame for System Performance IssuesEnough Blame for System Performance Issues
Enough Blame for System Performance Issues
 
Sharing our best secrets: Design a distributed system from scratch
Sharing our best secrets: Design a distributed system from scratchSharing our best secrets: Design a distributed system from scratch
Sharing our best secrets: Design a distributed system from scratch
 
Systems Monitoring with Prometheus (Devops Ireland April 2015)
Systems Monitoring with Prometheus (Devops Ireland April 2015)Systems Monitoring with Prometheus (Devops Ireland April 2015)
Systems Monitoring with Prometheus (Devops Ireland April 2015)
 
JavaOne 2015: Top Performance Patterns Deep Dive
JavaOne 2015: Top Performance Patterns Deep DiveJavaOne 2015: Top Performance Patterns Deep Dive
JavaOne 2015: Top Performance Patterns Deep Dive
 
B.tech admission in india
B.tech admission in indiaB.tech admission in india
B.tech admission in india
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - Talk
 
PlayStation and Lucene - Indexing 1M documents per second: Presented by Alexa...
PlayStation and Lucene - Indexing 1M documents per second: Presented by Alexa...PlayStation and Lucene - Indexing 1M documents per second: Presented by Alexa...
PlayStation and Lucene - Indexing 1M documents per second: Presented by Alexa...
 
OOSE UNIT-1.pdf
OOSE UNIT-1.pdfOOSE UNIT-1.pdf
OOSE UNIT-1.pdf
 
BPCS Infor ERP LX Implementation Evaluation Q4 2007
BPCS Infor ERP LX Implementation Evaluation Q4 2007BPCS Infor ERP LX Implementation Evaluation Q4 2007
BPCS Infor ERP LX Implementation Evaluation Q4 2007
 
P _n___l_accounting_website
P  _n___l_accounting_websiteP  _n___l_accounting_website
P _n___l_accounting_website
 
Asynchronous Apex Salesforce World Tour Paris 2015
Asynchronous Apex Salesforce World Tour Paris 2015Asynchronous Apex Salesforce World Tour Paris 2015
Asynchronous Apex Salesforce World Tour Paris 2015
 
AtlasCamp 2015: Damn you Facebook - Raising the bar in SaaS
AtlasCamp 2015: Damn you Facebook - Raising the bar in SaaSAtlasCamp 2015: Damn you Facebook - Raising the bar in SaaS
AtlasCamp 2015: Damn you Facebook - Raising the bar in SaaS
 
SBJUG - Building Beautiful Batch Jobs
SBJUG - Building Beautiful Batch JobsSBJUG - Building Beautiful Batch Jobs
SBJUG - Building Beautiful Batch Jobs
 
Sea of Data
Sea of DataSea of Data
Sea of Data
 

Recently uploaded

Enterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptxEnterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptx
QuickwayInfoSystems3
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Globus
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
takuyayamamoto1800
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Globus
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
Neo4j
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
AMB-Review
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
Georgi Kodinov
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
Adele Miller
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
wottaspaceseo
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
Globus
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Shahin Sheidaei
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Globus
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
Top 7 Unique WhatsApp API Benefits | Saudi Arabia
Top 7 Unique WhatsApp API Benefits | Saudi ArabiaTop 7 Unique WhatsApp API Benefits | Saudi Arabia
Top 7 Unique WhatsApp API Benefits | Saudi Arabia
Yara Milbes
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Mind IT Systems
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 

Recently uploaded (20)

Enterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptxEnterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptx
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
Top 7 Unique WhatsApp API Benefits | Saudi Arabia
Top 7 Unique WhatsApp API Benefits | Saudi ArabiaTop 7 Unique WhatsApp API Benefits | Saudi Arabia
Top 7 Unique WhatsApp API Benefits | Saudi Arabia
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 

Should you be using an event driven architecture?

  • 1. Should you be using an Event Driven Architecture? Jeppe Cramon - @jeppec Cloud Create ApS
  • 4. @jeppec “Example isn’t another way to teach, it is the only way to teach” Albert Einstein
  • 5. @jeppec Let’s look at Online Shopping
  • 6. @jeppec Most sites follow a similar pattern
  • 8. @jeppec public class OrderService { public void save(Order order) { orderRepository.add(order); if (inventoryService.areOrderItemsInStock(order)) { order.setStatus(OrderStatus.ItemsInStock); shippingService.startPackagingOrder(order); emailService.send(generateOrderOrderItemsInStockEmail(order)); } else { order.setStatus(OrderStatus.NotAllItemsInStock); emailService.send(generateOrderItemsNotInStockEmail(order)); executeMethod(OrderService::checkOrderInventoryStatus, Period.ofDays(1)); } } public void checkOrderInventoryStatus(OrderId orderId) { Order order = orderRepository.load(orderId); if (inventoryService.areOrderItemsInStock(order)) { order.setStatus(OrderStatus.ItemsInStock); shippingService.startPackagingOrder(order); emailService.send(generateOrderOrderItemsInStockEmail(order)); } else { executeMethod(OrderService::checkOrderInventoryStatus, Period.ofDays(1)); } } Side effect. What happens if we call save() twice?
  • 9. @jeppec public class OrderService { public void save(Order order) { orderRepository.add(order); if (inventoryService.areOrderItemsInStock(order)) { order.setStatus(OrderStatus.ItemsInStock); shippingService.startPackagingOrder(order); …
  • 10. @jeppec Let’s decouple Order- and Inventory Service further public class OrderService { public void save(Order order) { orderRepository.add(order); if (inventoryService.areOrderItemsInStock(order)) { order.setStatus(OrderStatus.ItemsInStock); shippingService.startPackagingOrder(order);
  • 11. @jeppec public class OrderService { public void save(Order order) { orderRepository.add(order); List<ProductId> productIdsOutOfStock = inventoryService.checkProductStockStatus( order.orderLines.toMap(OrderLine::productId, OrderLine::quantity)); if (productIdsOutOfStock.isEmpty()) { order.setStatus(OrderStatus.ItemsInStock); shippingService.startPackagingOrder(order); emailService.send(generateOrderOrderItemsInStockEmail(order)); } else { order.setStatus(OrderStatus.NotAllItemsInStock); emailService.send(generateOrderItemsNotInStockEmail(order, productIdsOutOfStock)); executeMethod(OrderService::checkOrderInventoryStatus, Period.ofDays(1)); } }
  • 13. @jeppec public class OrderService { public void save(Order order) { orderRepository.add(order); List<ProductId> productIdsOutOfStock = inventoryService.checkProductStockStatus( order.orderLines.toMap(OrderLine::productId, OrderLine::quantity)); if (productIdsOutOfStock.isEmpty()) { order.setStatus(OrderStatus.ItemsInStock); shippingService.startPackagingOrder(order); emailService.send(generateOrderOrderItemsInStockEmail(order)); } else { order.setStatus(OrderStatus.NotAllItemsInStock); emailService.send(generateOrderItemsNotInStockEmail(order, productIdsOutOfStock)); executeMethod(OrderService::checkOrderInventoryStatus, Period.ofDays(1)); } }
  • 14. @jeppec public class OrderService { public void save(Order order) { orderRepository.add(order); List<ProductId> productIdsOutOfStock = inventoryService.reserveProductsForOrder(order.orderId, order.orderLines.toMap(OrderLine::productId, OrderLine::quantity)); if (productIdsOutOfStock.isEmpty()) { order.setStatus(OrderStatus.ItemsInStock); shippingService.startPackagingOrder(order); emailService.send(generateOrderOrderItemsInStockEmail(order)); } else { order.setStatus(OrderStatus.NotAllItemsInStock); emailService.send(generateOrderItemsNotInStockEmail(order, productIdsOutOfStock)); executeMethod(OrderService::checkOrderInventoryStatus, Period.ofDays(1)); } } Introduces an additional side effect
  • 15. @jeppec Essential complexity of 2 way integration Inventory Service Order Service Shipping Service UI Start- Packaging Save-Order Order:Save-Order() call Inventory:Reserve-Products() call Shipping:Start-Packaging() commit() Reserve- Products Local transaction between the 3 “Services”
  • 17. @jeppec Accidental complexity from distributed service integration Inventory Service Order Service Shipping Service UI Start- Packaging Save-Order Reserve- Products Local transaction between 2 local “Services”Remote call
  • 19. @jeppec What’s the challenge with using a Pull model between distributed components?
  • 21. @jeppec Synchronous calls lower our tolerance for faults • When you get an IO error • When servers crash or restarts • When databases are down • When deadlocks occurs in our databases • Do you retry? With synchronous style Service interaction we can loose business data if there’s no automatic retry Or we risk creating data more than once if the operation isn’t idempotent* Client Server Duplicated Response Duplicated Request Processing Response Request Processing The same message can be processed more than once *Idempotence describes the quality of an operation in which result and state does not change if the operation is performed more than 1 time
  • 24. @jeppec Sales system Sale Delivery system Deliveries Customer/CRM system Customer SAP Bookkeeping Complete Purchase Transaction Coordinator Transactional Resource Prepare Phase Commit Phase 2 Phase Commit
  • 25. @jeppec What’s wrong with distributed transactions? • Transactions lock resources while active • Services are autonomous • Can’t be expected to finish within a certain time interval • Locking keeps other transactions from completing their job • Locking doesn’t scale • X Phase Commit is fragile by design
  • 26. @jeppec Using the pull model we’re prone to cascading failure
  • 27. @jeppec Order:Save-Order() call Inventory:Reserve-Products() call Shipping:Start-Packaging() if (Shipping:Call-Failed:Too-Busy?) Wait-A-While() call Shipping:Start-Packaging() if (Shipping:Call-Failed:Too-Busy?) Wait-A-Little-While-Longer() call Shipping:Start-Packaging() if (Shipping:Call-Failed:IO-Error?) Save-We-Need-Check-If-Call-Shipping-Succeded-After-All AND We-Need-To-Retry call Order:Save-Order and call Inventory:Reserve-Products AND Tell-Customer-That-This-Operation-Perhaps-Went-Well if (Shipping:Call-Went-Well?) commit() Accidental complexity from distributed service integration Inventory Service Order Service Shipping Service UI Start- Packaging Save-Order Reserve- Products Local transaction between 2 Components
  • 28. @jeppec “A distributed system is one where a machine I’ve never heard of can cause my program to fail” — Leslie Lamport
  • 29. @jeppec Service autonomy Order Inventory Shipping Retail System Shipping Order Inventory Retail System Slow/unreliable network Different SLA Slow system
  • 30. @jeppec Availability goes down (without additional instances of each service) Combined availability: 97%
  • 32. @jeppec But surely RPC is the only way to do this?
  • 33. @jeppec We need to switch from a pull to a push model Which means we need to change our approach slightly but profoundly
  • 34. @jeppec Most applications are built with CRUD as the main paradigm Intention gets lost
  • 35. @jeppec We need to shift focus from pure data towards intent and process automation This means a change from CRUD style application design, where the process was implicit and stored in the minds of the users First I need to enter the employee in this screen Then I need to press a button in the user system so they’re properly created And the I need to add their access card to this screen and press Activate
  • 36. @jeppec We need to capture User Intent at the UI CRUD style Task based style Intent
  • 37. @jeppec Task-based/Inductive UI • Traditional CRUD UI is what I would call a WHAT UI • Task based UI’s focuses on HOW the user wants to use the application • Guides users through the work process • The UI becomes an intrinsic part of the design • The UI design directly affects our commands and thereby our transactional boundaries
  • 38. @jeppec Capturing intent in the form of a Command A Command is prescriptive of what should happen, and its primary goal is to capture USER INTENT A Command supports a single usecase and targets a single business object within a single Transaction Commands always carry a name in its imperative form: • AcceptOrder • ShipOrder • CancelOrder • ReimburseCustomer • Etc. “A command describes a Task that you want someone else to carry out for you and where the recipient can choose to reject the Command”
  • 39. @jeppec Let’s capture the intent of the customer public class OrderService { public void handle(AcceptOrder cmd) { orderRepository.add(new Order(cmd.orderId, cmd.orderLines)); ???? }
  • 40. @jeppec How do we get the ball moving now that we can’t use RPC?
  • 41. @jeppec Life Beyond Distributed Transactions by Pat Helland 1. How do we split our data 2. How do we identify our data 3. How do we communicate between our services
  • 42. @jeppec 1. How do we split our data Data must be collected in pieces called aggregates. These aggregates should be limited in size (but not smaller), so that, after a transaction they are consistent. Rule of thumb: One transaction involves only one aggregate.
  • 43. @jeppec Domain Driven Design The term Aggregate comes from DDD
  • 44. @jeppec Aggregates Invoice InvoiceLine * Account * What: • Cluster coherent Entities and Value Objects, with complex associations into Aggregates with well defined boundaries. • Choose one entity to be root and control access to objects inside the boundary through the root. Motivation: Control invariants and consistency through the aggregate root. Ensuring consistency & transactional boundaries for Distributed scenarios! Root * *
  • 45. @jeppec 2. How do we identify our data According to Pat Helland we need to be able to uniquely identify each Aggregate using an ID. • This ID will usually a UUID/GUID {21EC2020-3AEA-4069-A2DD-08002B30309D} 2122 (approximately 5.3×1036) combinations
  • 46. @jeppec Aggregates refer to each other by ID they NEVER use memory pointers, join tables or remote calls
  • 47. @jeppec Services/Bounded Contexts and Aggregates Order Product Customer customerId … Order orderId customerId … OrderLine orderId productId quantity price ProductCategory productCategoryId … Product productId productCategoryId name tag ...
  • 48. @jeppec 3. How do we communicate between our services What do we do when our process involves more than one aggregate and therefore likely more than one service?
  • 49. @jeppec Synchronous calls are the crystal meth of programming At first you make good progress but then the sheer horror becomes evident when you realise the scalability limitations and how the brittleness holds back both performance and development flexibility. By then it is too late to save. http://www.infoq.com/news/2014/10/thompson-reactive-manifesto-2 We need the reactive properties and then apply protocols for the message interactions. Without considering the protocols of interaction this world of micro-services will become a coordination nightmare. Martin Thompson
  • 51. @jeppec Coupling matrix* * Modified version of Ian Robinson’s matrix: http://iansrobinson.com/2009/04/27/temporal-and-behavioural-coupling/ Behavioral coupling Temporal coupling Low High Low High Reactive/ Event oriented Command oriented Emergency services Distributed 3 layer
  • 52. @jeppec We need to change focus from short technical transactions To long running business transactions supporting business processes
  • 53. @jeppec Using Business Events to drive Business Processes Order Service Shipping Billing Sales Customers MessageChannel Online Ordering System Web Shop (Composite UI) Inventory Service Shipping Service Order Accepted AcceptOrder The sales fulfillment processing can now begin…
  • 54. @jeppec Events An Event is non-prescriptive of what should happen in other parts of the system. An event will typically be published to multiple consumers/subscribers: • The publisher of the event does not know who the subscribers are • And the publisher doesn’t know what the subscribers intend to do with the event Events always carry a name in its past-tense form: OrderWasAccepted OrderHasShipped CustomerWasReimbursed “An Event describes something that HAS happened”
  • 55. @jeppec Push model • Event based integration follows a push based model that breaks temporal coupling and avoids cascading failures • Events can be exchanged between services over a message channel (that can be implemented using a push or pull protocol) Sender Address Changed Event Receiver Address Changed Event Channel Asynchronous Communication – A.k.a. Messaging
  • 56. @jeppec Smart pipes and “dumb” endpoints – Push protocol Service X Publish Topic Data and flow direction Message infrastructure (e.g. Kafka, RabbitMQ, QBus) Service Z Subscribe Service Y Subscribe Service M Subscribe
  • 57. @jeppec Service X Publish Service Z Consume Service Y Consume Service M Consume Atom File based Feed generator Oldest Feed Older Feed Old Feed Feed Head Previous feed link HTTPEndpoint Next feed link Next feed link Previous feed link HTTP Reverse Proxy HTTP Reverse Proxy Cache Cache Atom Pub Feed as a JSON/XML file Dumb pipes and smart endpoints (Pull Protocol) Data and flow direction
  • 58. @jeppec Business Event as XML Message <OrderWasAccepted> <CustomerId>50D1F244-ABBC-4EC7-BDCA-E4934C124A89</CustomerId> <OrderId>C199322A-01F1-4E56-918E-7A63529F8FA3</OrderId> <ShippingAddress> ... </ShippingAddress> <BillingAddress> ... </BillingAddress> <Items> <Item ProductId="4CD22C4B-600C-4477-B5BF-48ABDEE4DA61" Amount="100" AmountUnit="Pieces" UnitPrice="100,10" UnitCurrency="EUR"/> <Item ProductId="56E6BD19-660C-464A-9120-100DAF579855" Amount="10" AmountUnit="Litres" UnitPrice="56,95" UnitCurrency="CHF"/> </Items> </OrderWasAccepted>
  • 59. @jeppec Business Event as JSON Message { EventType: "OrderWasAccepted", CustomerId: "50D1F244-ABBC-4EC7-BDCA-E4934C124A89", OrderId: "C199322A-01F1-4E56-918E-7A63529F8FA3", ShippingAddress: { ... } BillingAddress: { ... } Items: [ { ProductId: "4CD22C4B-600C-4477-B5BF-48ABDEE4DA61", Amount: "100", AmountUnit: "Pieces", UnitPrice: "100,10", UnitCurrency: "EUR" }, { ProductId: "56E6BD19-660C-464A-9120-100DAF579855", Amount: "10", AmountUnit: "Litres", UnitPrice: "56,95", UnitCurrency: "CHF" } ] }
  • 60. @jeppec Different uses for Events • Master data management and Data duplication • Data replication / migration • Notification • Service autonomy and Loosely coupled workflows/business processes across Services • UI component integration
  • 62. @jeppec System A System B System C System D 4 systems with shared data and no clear master for data
  • 64. @jeppec System A Update Customer Contact Info Update Customer ContactInfo Process ”UpdateCustomerContactInfo” command Event Publisher ”CustomerContactInfoUpdated” Event Customer View Customer local/cached replica System D BI/And other parties System B Customer Master
  • 65. @jeppec Event channel based migration New UI Old UI Command Action SQL D E <<Read replica>> C Publishes Events Event Publisher Channel SQL A B C
  • 66. @jeppec Example of Event based notification TrainPositionChanged TrainStopped TrainStarted … Every 5 ms. Subscriber A Subscriber B Subscriber C
  • 68. @jeppec Eventual consistency • Consistency is with each Service • Eventual consistency is between Services • Like in the real world Sales Invoicing Inventory Shipping Order Accepted Invoice Customer Checks Inventory for availability Books truck driver Order Packaged Fetch Package from Inventory Customer Invoiced
  • 71. @jeppec Choreographed Event Driven Processes Sales Service Order Accepted Billing Service Order Fulfilment (Saga/ Process-Manager) Shipping Service Online Ordering System MessageChannel(e.g.aTopic) Order Accepted Order Accepted Customer Billed Customer Billed Order Approved Order Approved Works as a Finite State Machine (WorkFlow) handling the life cycle of Shipping and thereby forms a very central new Aggregate in the System
  • 72. @jeppec Process Managers • Process Managers are essential to the coordination and monitoring of long running business processes/transactions • They work as a Finite State Machines (WorkFlow) which handling the life cycle of Process (e.g. Shipping an Order) and thereby forms a very central new Aggregate in the System • They can include manual steps/person intervention • Sometimes these Process Managers belong naturally within a specific Business capability and other times they are truly and thing by themselves and often form new business capabilities that way Many companies derive their competitive advantages from their Processes. A Process Manager allows you coordinate Business Processes on the basis of Events
  • 74. @jeppec Choreographed Event Driven Processes Order Service Order Accepted Inventory Service Shipping Service Online Ordering System MessageChannel(e.g.aTopic) Order Accepted Inventory Products Reserved Inventory Products Reserved Order Ready For Shipping Order Ready For Shipping
  • 75. @jeppec Accept Order flow public class OrderService { public void handle(AcceptOrder cmd) { orderRepository.add(new Order(cmd.orderId, cmd.orderLines)); publish(new OrderAccepted( cmd.orderId, cmd.orderLines.toMap(OrderLine::productId, OrderLine::quantity)) ); }
  • 76. @jeppec Inventory flow public class InventoryService { public void on(OrderAccepted e) { List<ProductId> productIdsOutOfStock = reserveProductsForOrder(e.orderId, e.productsToReserve); if (productIdsOutOfStock.isEmpty()) { publish(new InventoryProductsReserved(e.orderId, e.productsToReserve)); } else { publish(new InventoryProductsOutOfStock(e.orderId, e.productsToReserve, productIdsOutOfStock)); } }
  • 77. @jeppec Message Handling and Idempotence public class OrderShippingProcess { private void on(OrderPaid orderPaid, ProductsReserved productsReserved) { ShippingDetails shippingDetails = getShippingDetailsForOrder(orderPaid.orderId); …. printShippingLabel(orderPaid.orderId, shippingDetails.address); } … } Must also be idempotent
  • 78. @jeppec There are only two hard problems in distributed systems 2. Exactly Once Delivery 1. Guaranteed Order of Messages 2. Exactly Once Delivery @mathiasverraes
  • 79. @jeppec Things are not quite the same In a distributed systems the order in which messages arrive is not guaranteed In a distributed systems message delivery can and will fail! Messages can depending on guarantees be delivered: • At Most Once – If you don’t care about loosing messages • Page visits • Ad views • Other types of notifications • Exactly Once • Not really possible • At Least Once • For everything else – which is why: Everything that can handle messages must be built with idempotency in mind!
  • 80. @jeppec Event coordination • Do NOT copy data from incoming event to outgoing event – instead use Event coordination from the next slide Service C Event C Data: X Data: Y Data: C, Y Service D This form of data copying from incoming event to outgoing event is prohibited
  • 81. @jeppec Event coordination continued • Rule: If Service D also needs data from Event B, then Service D should also listen for Event B instead of having Service C copy data from Event B to Event C Service C Event C Data: X Data: Y Data: C Service D Data: Y
  • 82. @jeppec What should our Events look like? • Keep Events Small • Only include relevant metadata (such as sequence) and business data • If possible, don’t include unnecessary id’s for aggregates in other services • Think Inverse relationships based on what feels most natural • Order doesn’t need to know the Shipping Id, but Shipping can know the Order Id • Anchor Events to Time • Include information about how long you can trust the Event’s change • E.g. a price is valid until 8pm tomorrow night • Reveal the intention and time anchoring as part of the Events name
  • 83. @jeppec Internal vs External Events { EventType: ”OrderWasPaid", CustomerId: "50D1F244-ABBC-4EC7-BDCA-E4934C124A89", OrderId: "C199322A-01F1-4E56-918E-7A63529F8FA3", Amount: ….. } Internal Event: { EventType: "OrderWasPaid", OrderId: "C199322A-01F1-4E56-918E-7A63529F8FA3" } External Event:
  • 84. @jeppec Avoid using Events for generic services When ever a new Service is introduced the Generic Service (X) needs to be changed. This creates an unnecessary degree of coupling Service A Service B Service C Service X Service D Event X
  • 85. @jeppec Use Commands for generic services Instead of having Service X listen for MANY different events, let Service X expose a command interface that other services can use instead Service A Service B Service C Service X Service D Event X
  • 86. @jeppec When to prefer a Pull based model? • You want to have Authority (as opposed to Autonomy) • Such as with a bank account • GDPR compliance • So sensitive data is only stored in one place (avoid data duplication) • Orchestration of processes • Sometimes events result in too much ceremony • You have large amounts of data and your queries only involve a small set of this data • Example a Google search • Most UI to backend interactions • Loading data from the backend • Pressing a button to send a Query or issue a Command
  • 87. @jeppec How does shipping know where to ship items to?
  • 90. @jeppec Order Id • Customer/customer-id Linked to Order Id: • Order Delivery address • Order Shipping method Linked to Order Id: • Order shipping price
  • 91. @jeppec 91 Order OrderId Total DeliveryAddress Status … Decomposing the domain Order OrderId Total Status … ShippingDetails OrderId DeliveryAddress
  • 92. @jeppec Composite page example Page Context: {id: ISBN-10 0-321-83457-7 } Images Books Reviews Pricing Inventory OthersAlsoBought Pricing Reviews Books Images Books
  • 93.
  • 94. @jeppec Service Service - 1 Service - 2Service - 2 Service - 3 Service - 3Service - 4 Broker Broker (Kafka, RabbitMQ, JMS) Service - 1Service - 1 Service - 1 Service - 2 Service - 2 Service - 3 Service - 3 Service - 4 Service - 4 Service - 4
  • 95. @jeppec Service Service - 1 Service - 1Service - 1 Service - 1 Service - 2 Service - 2 Service - 2 Service - 2 Service - 3 Service - 3 Service - 3 Service - 3 Service - 4 Service - 4 Service - 4 Service - 4 QBus
  • 96. @jeppec pricing_engine_ac (deployed on 10.25.26.102) pricing_engine_ac (deployed on 10.25.26.101) Bus Bus Bus Bus inventory_ac (deployed on 10.25.26.104) inventory_ac (deployed on 10.25.26.103) Federated Bus
  • 97. @jeppec Topics Bus features • Decouples publisher from subscribers • Provides temporal decoupling • If a subscriber is unavailable it will receive its messages when it comes online Service - 4 Service - 1 Service - 3
  • 99. @jeppec Topics Bus features But how do we handle: • Coding errors in Subscribers? • New Subscribers that didn’t exist when the events were originally published? Service - 4 Service - 1 Service - 3
  • 101. @jeppec 1. Realization Commands and Queries support very different usecases
  • 102. @jeppec A single model cannot be appropriate for reporting, searching and transactional behavior Greg Young
  • 103. @jeppec The Triangular Architecture Task based UI Write ModelRead ModelRead Model Read Models
  • 104. @jeppec Commands & Events Commands mutate Write model state which results in one or more Events being published. Command Event(s) AcceptOrder OrderAccepted ShipOrder OrderShipped AddComment CommentAdded QuarantineReview ReviewQuarantined UnquarantineReview ReviewUnquarantined
  • 105. @jeppec The circle is completing
  • 106. @jeppec We can use Domain Events to build our View/Query models
  • 107. @jeppec Read model Read model Commands, Events and Query Models Events UI Write modelView models ”AcceptOrder” command ”OrderAccepted” event ”Find all Accepted Orders” Query Commands are Imperative: DoStuff Events are Past tense: StuffDone
  • 108. @jeppec CQRS Building blocks Client Commands Command Bus Sends Command Handlers Modify Repositories Read Write Data store Event Bus Event Handlers Events Read store Query HandlersQuery Results Queries Events Domain
  • 109. @jeppec Event Sourcing Write-Model/Aggregates track their own Domain Events and derive state from them Time 07:39 Time 07:40 Time 07:41 Time 07:45 Time 07:46 Time 07:50
  • 110. CRUD There’s no reason to delete data or update data. We only need to append and read Events from our Event Store
  • 111. @jeppec Event Replaying Type Aggregate Identifier Sequence Number Timestamp Event Identifier EventType SerializedEvent Order 14237 0 2014-01-06 7:39 {Guid-1} OrderCreated <serialized event>… Order 14237 1 2014-01-06 7:40 {Guid-2} ProductAdded <serialized event>… Order 14237 2 2014-01-06 7:41 {Guid-3} ProductAdded <serialized event>… Order 14237 3 2014-01-06 7:45 {Guid-4} ProductRemoved <serialized event>… Order 14237 4 2014-01-06 7:46 {Guid-5} ProductAdded <serialized event>… Order 14237 5 2014-01-06 7:50 {Guid-6} OrderAccepted <serialized event>… Order Accepted: true Orderline Orderline
  • 112. @jeppec Full CQRS with EventSourcing UI Domain Event Store Commands – Change data Commands Events SQL DB Document DB Graph DB UI Data Queries – Ask for data Events Query Build Our single source of truth
  • 113. @jeppec And we can use the EventStore to support event replays for new subscribers
  • 114. @jeppec Client handled subscriptions • Highly resilient pattern for an Event Driven Architecture that’s backed by Event-Sourced services • In this model the publisher of the Events is responsible for the durability of all its Events, typically to an EventStore/EventLog. • Each client (subscriber) maintains durable information of the last event it has received from each publisher. • When ever the client starts up it makes a subscription to the publisher where it states from which point in time it wants events published/streamed to it. • This effectively means that publisher can remain simple and the client (subscriber) can remain simple and we don’t need additional sophisticated broker infrastructure such as Kafka+ZooKeeper.
  • 115. @jeppec Client handled subscriptions Publisher Subscriber A Local storage EventStore Subscriber B Local storage Topic Subscription Topic Subscription TopicSubscriptionHandler TopicSubscriptionHandler EventEvent Event Event EventBus Event Event Distributed Event Bus, which ensures that live events published on an AC node in the cluster can be seen by all AC’s of the same type Singe Instance Subscriber, which ensures that only one instance of Subscriber B has an active subscription(s). Other instances of the same subscriber are hot-standby <<Topic Subscriber>> Customer_Service:Some_Ac:OrderEvents <<Topic Publisher>> Sales_Service:OrderEvents
  • 116. @jeppec Topics Bus features Service - 4 Service - 1 Service - 3 bus.registerReplayableTopicPublisher(InternalPricingEvents.TOPIC_NAME, replayFromAggregate(Pricing.class) .dispatchAggregateEventsOfType( InternalPricingEvents.class ) ); bus.subscribeTopic(SERVICE_AC_ID.topicSubscriber(”Pricing"), InternalPricingEvents.TOPIC_NAME, new PricingTopicSubscription(bus));
  • 117. @jeppec Topics public class PricingTopicSubscription extends BusMessageHandlerDelegator { @BusMessagePayloadHandler private void on(PrincingChanged e, BusMessage<PricingChanged> msg) { … } … }
  • 118. @jeppec Topics Bus features Features: • The Bus provides automatic and durable handling of Redelivery in case of message handling failure through a Redelivery Policy • Exponential Back-off • Max retries • Dead letter/Error Queue • Support for resubscription at any point in the timeline of an Event Stream • Automatically tracking of resubscription points - aka. resubscribe at last tracked point Service - 4 Service - 1 Service - 3
  • 119. @jeppec Can’t we just use Kafka?
  • 120. @jeppec With Kafka we still need smart endpoints
  • 122. @jeppec Bus features Features: • Support for sending a message to a single consumer • Default pattern is Competing Consumers • The bus provides durability for all messages sent on a Queue • The Bus provider automatic and durable handling of Redelivery in case of message handling failure through a Redelivery Policy • Exponential Backoff • Max retries • Dead letter/Error Queue Durable Queues
  • 123. @jeppec Can’t we just use Kafka?
  • 124. @jeppec Bus features Notifications: • Durable notifications with failover support • bus.notify(notificationQueue, notificationMessage) Notifications Distributed Broadcast Broadcast: • Broadcast a Message to all Services in the cluster • Broadcast a Message to a UI client (all, per user, per privilege)
  • 125. @jeppec Bus features Single Instance Task: • Ensures that only one Active instance of a Task is active in the cluster at one time • Other tasks of the same type are in hot standby • Used to e.g. group multiple subscribers, to ensure that all subscribers are either all active or standby. • Used by our ViewRepositories Distributed SingleInstanceTask bus.createClusterSingleInstanceTask(”MyTask", new MyTask ()); // Where MyTask implements Lifecycle
  • 126. @jeppec Bus features Process Manager • Defines durable business processes as a flow of Events Sagas Process Manager Sales Service Order Accepted Billing Service Order Fulfilment (Saga/ Process-Manager) Shipping Service MessageChannel(e.g.aTopic) Order Accepted Order Accepted Customer Billed Customer Billed Order Approved Order Approved
  • 127. @jeppec Application features Workflow Manager: • Defines the Tasks that required human intervention, such as: • Approvals (e.g. Contract approval) • Assistance/Help with a business problem • Incident handling (e.g. a technical problem identified by a developer) • Authorization (e.g. request manager approval) • Reminders • Common tasks supported: Claiming Tasks, Escalating Tasks, Completing Tasks Workflow Manager
  • 128. @jeppec Event Monitoring • One of the challenges with have Event based systems is to keep track of where events are in the flow • Why isn’t this system doing this? • Did events go into an Error Queue? • How can we reprocess them? • Or why isn’t this happening? • In general it’s the same issues we see with asynchronous systems and integrations in general. • The good thing about using Events is that they carry semantics and are not RPC in hiding
  • 129. @jeppec Event Monitoring Command, Document and Event messages all contain the following data: • Timestamp • Unique message Id • Correlation Id • Originating system (IP address, name, etc.) • … Event messages also need to describe the order in which the event occurred. This can be implemented in many ways including: • Ordering sequence number • Event vectors • Vector clocks • Timestamp • Etc.
  • 130. @jeppec Event Monitoring • We use the correlation id to be able to later correlate log messages from different services
  • 132. Thanks :) Blog: https://cramonblog.wordpress.com/ Homepage: http://cloudcreate.dk/ Twitter: @jeppec

Editor's Notes

  1. If both System A, B and C share the same technical infrastructure (e.g. database) and reside in the same memory space they can share a local transaction. In this case we’re not bound by the laws of distributed computing and everything is easy because the transaction manager will solve all our problems.
  2. Synchronous RPC is the crack cocaine of distributed programming
  3. Locking and scaling: If it takes 200 ms to carry out an operation that uses scaling, the system can maximum handle 5 concurrent users Fragility: 2,3,4 .... Phase Commit - 2PC theory concludes by saying "and this does not work in reality" - in case of error (eg. Due to timeout while waiting for a resource commit phase) you always end up with having to decide what two do "Halt and manual recovery" or guess whether it was good or bad! There are besides timeouts a big problem. At worst, timeouts last very long!
  4. See http://cqrs.wordpress.com/documents/task-based-ui/ for more
  5. CRUD = Create Read Update Delete
  6. There’s no intent in a Save button. In the CRUD screen you can combine multiple usecases into one (edit title, assign to user, complete, change description). In the Task based example you focus on one usecase at a time (which can be a composite/process related usecase) and ensure that the user interface reflects the users mental model (has relevant information for the user to complete the task) and captures the users intent.s
  7. Aggregates reference each other by Id only in a scalable system An Aggregate Root is more likely to match a Use Case boundary than any model structure
  8. Who informs the customer? What happens if Billing fails or times out?
  9. This minimizes the number of events that Service X (in this example) needs to understand and know. Here we trade data coupling for functional coupling
  10. This minimizes the number of events that Service X needs to understand and know. Here we trade data coupling for functional coupling It’s a choice between Loose Coupling and High Cohesion. If Service X needs to understand too MANY Events from other services, then his cohesion becomes lower and thereby the coupling gets higher
  11. Our read model is structurally oriented (the users perspective on the data in the given context) The write model is behavioural oriented (transaction and consistency boundary oriented)
  12. From http://www.codeagle.com/blog/2010/03/10/275/
  13. EventStore: Why store only the current state of the system. Mature industries store transactions and calculate the current state
  14. /Users/jeppe/git/finnova/demo-app/tellerapp