SlideShare a Scribd company logo
1 of 156
Should you be using an Event
Driven Architecture?
Jeppe Cramon - @jeppec
Cloud Create ApS
Or what 15+ years of distributed
systems implementation
has taught me
Jeppe Cramon - @jeppec
Cloud Create ApS
@jeppec
What mistakes can we learn
from?
@jeppec
Data
Storage
Data Storage
Data
Storage
Portal 1 Portal 2
Data
Storage
Application
Process Service layer
Activity/Task Service layer
Data/Entity Service layer
Layered SOA
@jeppec
Remote Call
Aka. RPC/REST/SOAP/GraphQL…
@jeppec
What’s the challenge using
state mutating
Request/Response calls
between
distributed components?
@jeppec
Synchronous Request/Response
lowers 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 Request/Response we can loose business data if there’s no automatic retry mechanism.
Also if the operation we retry isn’t idempotent* we risk having the side effect multiple times!
Client Server
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
Request
Processing
Duplicated Request
Duplicated Response
Response
@jeppec
Idempotence
Don’t press the refresh button!
@jeppec
Data
Storage
Data Storage
Data
Storage
Portal 1 Portal 2
Data
Storage
Application
Process Service layer
Activity/Task Service layer
Data/Entity Service layer
Layered SOA
@jeppec
Be careful you don’t split the atom
@jeppec
Services != Decoupling
@jeppec
Resemble much?
@jeppec
Distributed Queries anyone?
@jeppec
Ensuring
transactional
consistency
becomes much harder
@jeppec
Sales system
Sales
Delivery
system
Deliveries
Customer/
CRM system
Customers
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
Learnings
• Task/Activity services needs to perform UPDATES across multiple
data/entity services. Requires distributed transactions or fully
asynchronous process management.
• The more synchronous request-response remote calls you have to
make the more it hurts Performance and latency.
• Robustness is lower. If one data/entity services is down it can take
down many other services.
• Coupling is higher. Multiple task/activity services manage the same
CRUD data/entity services
• Cohesion is likely lower as multiple task/activity services need to
replicate entity related logic
@jeppec
Conclusion
Friends don’t let friends use layered SOA
@jeppec
But we surely don’t have this
problem today!
@jeppec
Let’s take a concrete example
From online shopping
@jeppec
Online shopping
@jeppec
Essential complexity of 2 way integration
Component
Warehouse
Component
Order
Component
Billing
UI
Send-Invoice Save-Order
Sales:Save-Order()
call Warehouse:Reserve-Items()
call Billing:Send-Invoice()
commit()
Reserve-
Items
Local transaction between the 3
Components
@jeppec
Let’s (micro)service’ify this
@jeppec
Accidental complexity from distributed service integration
Warehouse
Service
Order
Service
Billing
Service
UI
Send- Invoice Save-Order
Reserve-
Items
Local transaction between 2 local
“Services”
Remote call
@jeppec
Microservices turns a
local functional call
into a distributed problem
@jeppec
Dual write problem
Order
Service
Billing
Service
Client
Send- Invoice
Save-Order
Remote call
causing a side
effect
Expected transaction
boundary
No simple solution (except a classic monolith)
• Local-commit-then-publish
• If the app crashes after local-
commit then the publish
operation isn’t performed
• Publish-then-local-commit
• If the local-commit fails then
we’ve already formed the publish
operation
• Billing Service may receive
published message BEFORE the
Order Service has committed
its transaction
@jeppec
Order:Save-Order()
call Warehouse:Reserve-Items()
call Billing:Send-Invoice()
if (Billing:Call-Failed:Too-Busy?)
Wait-A-While()
call Billing:Send-Invoice()
if (Billing:Call-Failed:Too-Busy?)
Wait-A-Little-While-Longer()
call Billing:Send-Invoice()
if (Billing:Call-Failed:IO-Error?)
Save-We-Need-Check-If-Call-Billing-Succeded-After-All
AND We-Need-To-Retry call Order:Save-Order and call Warehouse:Reserve-Items
AND Tell-Customer-That-This-Operation-Perhaps-Went-Well
if (Billing:Call-Went-Well?)
commit()
Accidental complexity from distributed service integration
Warehouse
Service
Order
Service
Billing
Service
UI
Send- Invoice Save-Order
Reserve-
Items
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 Warehouse
Billing
Retail System
Billing
Order Warehouse
Retail System
Slow/unreliable network
Different SLA
Slow system
@jeppec
Availability goes down
(without additional instances of each service)
Combined availability: 97%
@jeppec
Solution
Model our data and usecases, so that all our overall usecase can be
turned into a set of indepent transactions that are asynchronously
chained.
Accept
Order
?
Receive
Payment
?
Ship
Order
This means that our business data must be collected in Entities,
that should be limited in size (but not smaller),
so that, after a transaction they are consistent
(Pat Helland – Life Beyond Distributed Transactions)
@jeppec
But surely RPC is the only way
to coordinate this?
@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
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
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 a FACT, i.e., something that HAS happened”
@jeppec
Different uses for Events
• Master data management and Data duplication
• Data replication / migration
• Notification
• UI component integration
• Service autonomy and Loosely coupled workflows/business processes
across Services
@jeppec
This means we must switch from
a
Request/Response (pull)
to a
Reactive (push) model
A change with profound consequences
@jeppec
How do we get the
ball rolling now that we can’t
use RPC?
@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
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
We need to capture User Intent at the UI
CRUD style
Task based style
Intent
@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
Commands & Events symmetry
• Commands change Business Object (Entity) state which results in one
or more Events being published.
Command Event(s)
AcceptOrder OrderAccepted
ShipOrder OrderShipped
AddComment CommentAdded
QuarantineReview ReviewQuarantined
UnquarantineReview ReviewUnquarantined
Command Event
@jeppec
Command to Event
public class OrderService {
public void handle(AcceptOrder cmd) {
orderRepository.add(new Order(cmd.orderId,
cmd.orderLines));
eventBus.publish(new OrderAccepted(cmd.orderId,
cmd.orderLines));
}
@jeppec
Unambigous commands?
Order Id?
•Is it ISO-4217 3 characters
currency code (such
as USD and DKK)?
•Is it ISO-4217 Currency numbers
(such as 840 and 208)?
•Is it the currency name (such as US
Dollar and Danish Krone)?
•Is it the sales tax as
a Percentage ?
•Is it the calculated sales
tax as an Amount ?
•Is
the key the ProductId ?
•Is the value a Quantity ?
AcceptOrder
@jeppec
Using Essential Types
https://github.com/cloudcreate-dk/essentials/tree/main/types
AcceptOrder
@jeppec
Using Business Events to drive Business Processes
Sales Service
Shipping
Billing
Sales
Customers
Message
Channel
Online Ordering System
Web Shop
(Composite UI)
Billing Service
Warehouse Service
<<External>>
Order Paid
MarkOrderAsPai
d
The sales
fulfillment
processing can
now begin…
Cmd Handler
Order Paid
Apply
@jeppec
Business Processes
@jeppec
We need to change focus from short
technical transactions
To long running business transactions supporting
business processes
@jeppec
Choreographed Event Driven Processes
Sales Service
Order Paid
Billing Service
Shipping Service
Warehouse Service
Online Ordering System
Message
Channel
(e.g.
a
Topic)
Order Paid
Customer
Invoiced
Order Paid
Items
Reserved
Order Paid
Shipping process
works as a Finite
State Machine
(WorkFlow)
handling the life
cycle of Shipping and
thereby forms a very
central new
Aggregate in the
System
Items
Reserved
@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
Equally important!
Focus on identifying IF you’re within the
happy path of the process
From a ROI perspective many edge cases
are better handled by humans than trying
to automate them
@jeppec
Event communication
@jeppec
Reactive/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
Publisher
Subscriber
Asynchronous Communication – A.k.a. Messaging
Customer Moved
Customer Moved
Subscriber
Customer Moved
Channel
@jeppec
Smart pipes and “dumb” endpoints – (Push protocol)
Service X
Publisher
Data and flow direction
Message infrastructure
(e.g. Kafka, RabbitMQ, …)
Service Z
Subscriber
Service Y
Subscriber
Service M
Subscriber
Topic
@jeppec
Service X
Publisher
Service Z
Consumer
Service Y
Consumer
Service M
Consumer
Atom File based Feed
generator
Oldest
Feed
Older
Feed
Old
Feed
Feed
Head Previous feed link
HTTP
Endpoint
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
Topic features
• Decouples publisher from subscribers
• Provides temporal decoupling
• If a subscriber is unavailable, it will receive its messages when it comes
online
Topics
Service - 4
Service - 1
Service - 3
@jeppec
Topic and event flow
CreateOrder
Sales_Service:Orders_Ac
Webshop Application
Customer_Service:Some_Ac
OrderCreated
OrderCreatedEvent
Publish
CreateSomeRelatedAggregate
Sales_Service:OrderEvents
<<Topic>>
OrderCreatedEvent
@jeppec
There’s just one issue
public class OrderService {
public void handle(AcceptOrder cmd) {
orderRepository.add(new Order(cmd.orderId,
cmd.orderLines));
eventBus.publish(new OrderAccepted(cmd.orderId,
cmd.orderLines));
}
Dual Write problem still
exists!
@jeppec
How can we solve this issue?
@jeppec
Dual write problem
using Event Sourcing
Order
Service
Billing
Service
Client
Send- Invoice
Save-Order
Transaction
boundary
Transaction
boundary
Event Store
• Requires only local transactions
• Natively event driven: The Service
consumes and produces events
• Proven Audit Trail
• Flexible and adaptable
• Captures business intentions as events
• Requires idempotent operations
@jeppec
Event Sourcing
Business-Objects/Aggregates track their own Domain Events
and derive their state from said Events
Time
07:39
Time
07:40
Time
07:41
Time
07:45
Time
07:46
Time
07:50
@jeppec
Typed Events
public class OrderAdded extends Event<OrderId> {
public final CustomerId orderingCustomerId;
public final long orderNumber;
public OrderAdded(OrderId orderId, CustomerId orderingCustomerId, long orderNumber) {
aggregateId(orderId);
this.orderingCustomerId = orderingCustomerId;
this.orderNumber = orderNumber;
}
}
public class ProductAddedToOrder extends Event<OrderId> {
public final ProductId productId;
public final int quantity;
public ProductAddedToOrder(ProductId productId, int quantity) {
aggregateId(orderId);
this.productId = productId;
this.quantity = quantity;
}
}
CRUD
There’s no reason to delete data or update data.
We only need to append and read Events from our Event Store
@jeppec
Full CQRS with EventSourcing
UI Domain
Event
Store
Commands – Change data
Commands Events
UI Data
Queries – Ask for data
Events
Query Build
Our single source
of truth
SQL DB Graph DB
Document DB
@jeppec
Typed Aggregate
public class Order extends AggregateRoot<OrderId, Order> {
private Map<ProductId, Integer> productAndQuantity;
private boolean accepted;
public Order(OrderId orderId,
CustomerId orderingCustomerId,
int orderNumber) {
FailFast.requireNonNull(orderId, "You must provide a orderId");
FailFast.requireNonNull(orderingCustomerId, "You must provide an
orderingCustomerId");
apply(new OrderAdded(orderId,
orderingCustomerId,
orderNumber));
}
public void addProduct(ProductId productId, int quantity) {
FailFast.requireNonNull(productId, "You must provide a productId");
if (accepted) {
throw new IllegalStateException("Order is already accepted");
}
apply(new ProductAddedToOrder(productId, quantity));
}
@jeppec
Event Replaying
Type Aggregate
Identifier
GlobalOrder Sequence
Number
Timestamp Event
Identifier
EventType SerializedEvent
Order 14237 100 0 2014-01-06 7:39 {Guid-1} OrderCreated <serialized event>…
Order 14237 101 1 2014-01-06 7:40 {Guid-2} ProductAdded <serialized event>…
Order 14237 102 2 2014-01-06 7:41 {Guid-3} ProductAdded <serialized event>…
Order 14237 103 3 2014-01-06 7:45 {Guid-4} ProductRemoved <serialized event>…
Order 14237 104 4 2014-01-06 7:46 {Guid-5} ProductAdded <serialized event>…
Order 14237 105 5 2014-01-06 7:50 {Guid-6} OrderAccepted <serialized event>…
Order
Accepted: true
Orderline
Orderline
@jeppec
Aggregate replay
public class Order extends AggregateRoot<OrderId, Order> {
private Map<ProductId, Integer> productAndQuantity;
private boolean accepted;
public void accept() {
if (accepted) {
return;
}
apply(new OrderAccepted());
}
@Override
protected void applyEventToTheAggregate(Event<OrderId> event) {
if (event instanceof OrderAdded e) {
productAndQuantity = HashMap.empty();
} else if (event instanceof ProductAddedToOrder e) {
Option<Integer> existingQuantity = productAndQuantity.get(e.productId);
productAndQuantity = productAndQuantity.put(e.productId, e.quantity + existingQuantity.getOrElse(0));
} else if (event instanceof ProductOrderQuantityAdjusted e) {
productAndQuantity = productAndQuantity.put(e.productId, e.newQuantity);
} else if (event instanceof ProductRemovedFromOrder e) {
productAndQuantity = productAndQuantity.remove(e.productId);
} else if (event instanceof OrderAccepted) {
accepted = true;
}
}
@jeppec
Topic features
But how do we handle:
• Coding errors in Subscribers?
• New Subscribers that didn’t exist when the events were originally
published?
Topics
Service - 4
Service - 1
Service - 3
@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
RSocketEvent
StreamSubscription
Local storage
EventStore
RSocketEvent
StreamSubscription
Local storage
EventStreamSubscription
Message
EventStreamSubscription
Message
EventStoreEventStreamPublisher
EventStoreEventStreamPublisher
Event
Event
Event Event
Supports
Single Instance
Subscriber, which
ensures that only
one instance of
Subscriber B has
an active
subscription.
Other instances of
the same
subscriber are
hot-standby
<<Topic Subscriber>>
Customer_Service:Some_Ac:OrderEvents
<<Topic Publisher>>
Sales_Service:OrderEvents
RSocketServer
tcp://subscribe-event-stream
A
B
Subscriber B
RSocket Request/Stream
Event-Stream
Subscriber A
RSocket Request/Stream
Event-Stream Flux<PersistedEvent> eventStream(long fromInclusiveGlobalOrd
Option<String> subscripti
@jeppec
ReactiveBus Pub/Sub
JdbcEventStores eventStores = ….
var customerAggregateType = AggregateType.from("Customer", CustomerTestEvents.CustomerId.class);
var customerEventStore = eventStores.getEventStoreFor(customerAggregateType);
var streamName = EventStreamName.from("CustomersStream");
reactiveBus.addEventStreamPublisher(new EventStoreEventStreamPublisher(streamName, customerEventStore,
unitOfWorkFactory));
Publisher:
reactiveBus.subscribeToEventStream(
SubscriberId.from(”SalesService->CustomerEvents"),
EventStreamName.from("CustomersStream"),
EventStreamSubscriptionParameters.parameters(GlobalOrderSubscribeFromToken.fromStartOfStream()))
.doOnNext(payload -> {
System.out.println(”Received: " + e.payload.getClass() + "@" + e.globalOrder);
}).subscribe();
Subscriber:
@jeppec
Pub/Sub – Subscriber event handling
reactiveBus.subscribeToEventStream(SubscriberId.from(”SalesService->OrderEvents"),
EventStreamName.from(”OrdersStream"),
EventStreamSubscriptionParameters.parameters(GlobalOrderSubscribeFromToken.fromStartOfStream
.doOnNext(payload -> {
if (event instanceof OrderAdded e) {
.. = e.orderNumber;
} else if (event instanceof ProductAddedToOrder e) {
… = e.productId;
} else if (event instanceof OrderAccepted) {
…accepted = true;
}
).subscribe();
@jeppec
Pub/Sub – Subscriber event handling
@EventHandler
private void handle(OrderAdded e, EventMessage message) {
….
}
@EventHandler
private void handle(ProductAddedToOrder e) {
.…
}
@EventHandler
private void handle(OrderAccepted e) {
….
}
@jeppec
Event Design
@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
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
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
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
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 system the order in which messages arrive is not
guaranteed
In a distributed systems message delivery can and will fail!
Messages can be delivered according to these guarantees:
• At Most Once – If you don’t care about loosing messages
• Page visits
• Ad views
• 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
Message Handling
public class OrderShippingProcess extends MessageHandler {
@MessageHandler
private void on(OrderPaid orderPaid, ItemsReserved itemsReserved) {
ShippingDetails shippingDetails = getShippingDetailsForOrder(orderPaid.orderId);
….
printShippingLabel(orderPaid.orderId, shippingDetails.address);
}
…
} Must also be idempotent
@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
• Caused by Event 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
Correlation logging
Source: https://docs.particular.net/serviceinsight/#flow-diagram
@jeppec
When to prefer a Request/Response (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 event choreography can 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 (e.g. Accept Order)
@jeppec
How to design services that
are loosely coupled?
@jeppec
"I consider 'getting the boundaries
right' the single design decision with
the most significant impact over the
entire life of a software project."
@ziobrando
@jeppec 94
@jeppec
This highly depends on
• How likely are things to change
• And what parts that change together
@jeppec
@jeppec
Result is often fragmented domain logic
Focus on Nouns (Entities)
and retrofit Verbs later
@jeppec
Customer
CustomerId
FirstName
LastName
Email
…
Order
OrderId
Total
DeliveryAddress
Status
…
OrderLine
Quantity
Product
ProductId
Name
Images
Price
Others have bought
@jeppec
If we primarily model around nouns/entities we can
easily violate the SRP
Where a change to requirements
is likely to require changes
to multiple entity classes
@jeppec
Business introduces new rule
Product price depends on Customer Status
@jeppec
Customer
CustomerId
FirstName
LastName
Email
Status
…
Order
OrderId
Total
DeliveryAddress
Status
…
OrderLine
Quantity
Product
ProductId
Name
Description
Images
Price
Others have bought
What now?
@jeppec
Jim Coplien
@jeppec
instead of focusing on Nouns!
@jeppec
When discussing use cases with Business Experts
@jeppec
and what fields that are separate
@jeppec
@jeppec
Customer
CustomerId
FirstName
LastName
Email
Status
…
Product
ProductId
Name
Description
Images
Price
Decomposing the domain
Customer
FirstName
LastName
Customer
Status
Product
Price
Product
Name
Description
@jeppec
But don’t name the piles before you know what they are
This avoids cognitive bias!
@jeppec
Give the piles made up names, such as colors
@jeppec
What are these problem domain piles?
@jeppec
@jeppec
If we align the problem domain with the solution domain
Bounded Context 1 Bounded Context 3
Bounded Context 2
UI
BL
DAO
UI
BL
DAO
UI
BL
DAO
Vertical coupling
is
unavoidable
We want to avoid
horizontal coupling
@jeppec
What are the solution domain piles?
113
@jeppec
A Service is
• The technical authority for a given bounded context
• It is the owner of all the data and business rules that support this
bounded context – everywhere
• It forms a single source of truth for that bounded context
http://udidahan.com/2010/11/15/the-known-unknowns-of-soa/
@jeppec
Be aware of Conways Law
“organizations which design systems ... are constrained to produce
designs which are copies of the communication structures of these
organizations”
Teams are typically aligned with Systems
and NOT with Services as they should
Said another way: How you organize yourself, determines your architecture
@jeppec
Business Capability alignment
“The advantage of business capabilities is their remarkable level of
stability. If we take a typical insurance organisation, it will likely
have sales, marketing, policy administration, claims management,
risk assessment, billing, payments, customer service, human
resource management, rate management, document
management, channel management, commissions management,
compliance, IT support and human task management capabilities.
In fact, any insurance organisation will very likely have many of
these capabilities.”
See http://bill-poole.blogspot.dk/2008/07/business-capabilities.html
@jeppec
Business – IT alignment
• We want the Business and IT to speak the same Ubiquitous language
• Want want our architecture to be aligned with the business capabilities
• Because these capabilities are stable
@jeppec
Many perspectives on data
Online Retail System
Product
Unit Price
Promotional Price
Promotion End Date
Stock Keeping Unit (SKU)
Quantity On Hand (QOH)
Location Code
Price
Quantity Ordered
Name
The lifecycle of the data is VERY important!
Customer
Pricing
Inventory
Sales
Management Reporting
@jeppec
Smaller models & clear data ownership
Retail System
Pricing
Product
ProductID
Unit Price
Promotional Price
…
Pricing
Inventory
Product
ProductID
SKU
QOH
Location Code
…
Inventory
Sales
Product
ProductID
Name
Description
Quantity Ordered
…
Sales
Shared Entity identity
DDD:
Bounded
Context
Business
Capability Service
@jeppec
Bounded Contexts and Aggregates
Sales
Product
Customer
customerId
…
Order
orderId
customerId
…
OrderLine
orderId
productId
quantity
timestamp
priceId
ProductCategory
productCategoryId
…
Pricing
Product
productId
productCategoryId
name
tag
...
Product-Price
priceId
productId
normalPrice
discountPeriods
…
@jeppec
Using Business Events to drive Business Processes
Sales Service
Shipping
Billing
Sales
Customers
Message
Channel
Online Ordering System
Web Shop
(Composite UI)
Billing Service
Shipping Service
<<External>>
Order Accepted
AcceptOrder
The sales
fulfillment
processing can
now begin…
Cmd Handler
Order Accepted
Apply
@jeppec 122
@jeppec
Microservices promise a solution
to our problem
Monolith
Microservice Microservice
Microservice Microservice
Microservice
Microservice
Microservice
@jeppec
There’s never time to do it right
But there’s always time to do it over
124
@jeppec
Microservices is an architectural style
125
@jeppec 126
@jeppec
Service and deployment
• A Service represents a logical responsibility boundary
• Logical responsibility and physical deployment of a Service
DOES NOT have to be 1-to-1
• It’s too constraining
• We need more degrees of freedom
• Philippe Krutchen 4+1 views of architecture: Logical and Physical
designs should be independent of each other
A service needs to be deployed everywhere its data is needed
@jeppec
@jeppec
Service Microservices
1..*
Is implemented by
A Service is the technical authority of a specific
Bounded-Context/Business Capability
e.g. Sales, Shipping, Billing
Service vs Microservices
@jeppec
Service Microservices
1..*
Is implemented by
Service vs Microservices
Microservices are a division of Services along Transactional boundaries (a transaction stays within the
boundary of a Microservice)
Microservices are the individual deployable units of a Service with their own Endpoints. Could e.g. be the
split between Read and Write models (CQRS) - each would be their own Microservices
@jeppec
A Service represents a logical boundary
131
Service
Microservice
Microservice Microservice
Microservice
@jeppec
Services are the corner stone
• We talk in terms of Services capabilities and the processes/use-cases
they support
• Microservices are an implementation detail
• They are much less stable (which is a good thing – it means they’re easier to
replace)
@jeppec
Service deployment
• Many services can be deployed to the same physical server
• Many services can be deployed in the same application
• Application boundary is a Process boundary which is a physical boundary
• A Service is a logical boundary
• Service deployment is not restricted to tiers either
• Part of service A and B can be deployed to the Web tier
• Another part of Service A and B can be deployed to the backend/app-service tier of the same
application
• The same service can be deployed to multiple tiers / multiple applications
• ie. applications and services are not the same and does not share the same boundaries
• Multiple services can be “deployed” to the same UI page (service mashup)
@jeppec
What about Security
Is Security a Service?
• If it’s technical YES
• Example: Authentication & Authorization
• If it’s a business related, i.e. Business rule, – NO
• Then it belongs inside the Service responsible for this business capability
• Example: Who’s allowed to authorize large transfers or who’s allowed to
reimburse the customer
@jeppec
How do we bring things together for our users
without introducing unnecessary coupling?
@jeppec
Let’s look at Applications
@jeppec
iOS Home Banking
Customer information
Legal and contract information
Accounts
@jeppec
iOS Home banking
Customer information
Legal and contract information
Accounts
Credit card
Mortgage loans
Web banking portal
Bank Back-office application
@jeppec
Let’s assume we have these services
Currency
Service
Customer
Service
Identity
Management
Service
Sales
Service
Inventory
Service
Products
Service
IT Operations
Shipping
Service
Web Shop
@jeppec
Back-end for Front-end?
Client
Remote Facade
DTOs
Identity
Management
Service
Customer
Service
Products
Service
Sales
Service
Inventory
Service
Shipping
Service
Currency
Service
IT Operations
@jeppec
Service A Service B Service C
IT-OPS
Web shop
Warehouse
Back office
App logic
(Layered, CQRS,…)
Warehouse
Storage
UI Components
A Services owns its UI Components
@jeppec
@jeppec
@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
A Service represents a logical boundary
Service
Microservice
Autonomous
Component
Adapter
UI component
@jeppec
An Application is the plate where Components are
co-deployed
Sales service components
Inventory service components
…
@jeppec
An UI is composed of
widgets from
different services
@jeppec
Service Widget Service Widget
Page
Service Widget
Service Widget
Service Widget
• Overall structure of the page
is “owned” by the application.
• Each service widget is independent
Composite page layout
Service Widget Service Widget Service Widget
Service Widget
@jeppec
https://our.micro-cool.bank-portal
Customer
Name: Peter Hansen
Address: Some Road 1
Some Zip Some City
Customer relations
Spouse: Mette Hansen
Children: Jacob Hansen
Ditte Hansen
Overview Page
(owned by the
application)
<<UI Component>>
Customer Details Component
<<UI Component>>
Customer Relations
Component
UI layer
Backend layer
Customer Details
Microservice
Customer Relations
Microservice
HTTPS HTTPS
@jeppec
@jeppec
Page Rendering Example
Page Ctrl
Sales
Service
UI Broker
Customer
Service
Pricing
Service
Product
Service
Page
Widget
Ctrl
Widget
Ctrl
Widget
Ctrl
Widget
Ctrl
Widget
Ctrl
Widget
Ctrl
Widget
Ctrl
Widget
Ctrl
1.
Backend
API
Backend
API
Backend
API
Backend
API
2.
3.
4.
5.
5.
6.
7.
7.
7.
7.
5.
8.
8.
8.
8.
@jeppec
Self Contained Systems
LINKS / REDIRECTIONS UI INCLUSION
https://scs-architecture.org
@jeppec
Hyperlinks – Navigation between Systems
@jeppec
Redirection – Bi-directional navigation
@jeppec
Dynamic Inclusion
Content served by another application within a
self contained system
Thanks :)
Blog: https://cramonblog.wordpress.com/
Homepage: http://cloudcreate.dk/
Twitter: @jeppec

More Related Content

What's hot

Event Driven Microservices architecture
Event Driven Microservices architectureEvent Driven Microservices architecture
Event Driven Microservices architectureNikhilBarthwal4
 
Event Driven Architecture
Event Driven ArchitectureEvent Driven Architecture
Event Driven ArchitectureChris Patterson
 
Object oriented software engineering concepts
Object oriented software engineering conceptsObject oriented software engineering concepts
Object oriented software engineering conceptsKomal Singh
 
Introduction to Modern Software Architecture
Introduction to Modern Software ArchitectureIntroduction to Modern Software Architecture
Introduction to Modern Software ArchitectureJérôme Kehrli
 
Architectural structures and views
Architectural structures and viewsArchitectural structures and views
Architectural structures and viewsDr Reeja S R
 
Object oriented vs. object based programming
Object oriented vs. object based  programmingObject oriented vs. object based  programming
Object oriented vs. object based programmingMohammad Kamrul Hasan
 
Event-driven microservices
Event-driven microservicesEvent-driven microservices
Event-driven microservicesAndrew Schofield
 
Event Driven Architecture
Event Driven ArchitectureEvent Driven Architecture
Event Driven ArchitectureStefan Norberg
 
Deadlock Avoidance - OS
Deadlock Avoidance - OSDeadlock Avoidance - OS
Deadlock Avoidance - OSMsAnita2
 
Software Architecture Patterns
Software Architecture PatternsSoftware Architecture Patterns
Software Architecture PatternsAssaf Gannon
 
Object Oriented Analysis and Design
Object Oriented Analysis and DesignObject Oriented Analysis and Design
Object Oriented Analysis and DesignHaitham El-Ghareeb
 
INTRODUCTION TO UML DIAGRAMS
INTRODUCTION TO UML DIAGRAMSINTRODUCTION TO UML DIAGRAMS
INTRODUCTION TO UML DIAGRAMSAshita Agrawal
 
Object Oriented Approach for Software Development
Object Oriented Approach for Software DevelopmentObject Oriented Approach for Software Development
Object Oriented Approach for Software DevelopmentRishabh Soni
 
Uml deployment diagram
Uml deployment diagramUml deployment diagram
Uml deployment diagramAsraa Batool
 

What's hot (20)

Event Driven Microservices architecture
Event Driven Microservices architectureEvent Driven Microservices architecture
Event Driven Microservices architecture
 
High–Performance Computing
High–Performance ComputingHigh–Performance Computing
High–Performance Computing
 
Event Driven Architecture
Event Driven ArchitectureEvent Driven Architecture
Event Driven Architecture
 
Object oriented software engineering concepts
Object oriented software engineering conceptsObject oriented software engineering concepts
Object oriented software engineering concepts
 
Event-driven Architecture
Event-driven ArchitectureEvent-driven Architecture
Event-driven Architecture
 
Use Case Modeling
Use Case ModelingUse Case Modeling
Use Case Modeling
 
Introduction to Modern Software Architecture
Introduction to Modern Software ArchitectureIntroduction to Modern Software Architecture
Introduction to Modern Software Architecture
 
Architectural structures and views
Architectural structures and viewsArchitectural structures and views
Architectural structures and views
 
Object oriented vs. object based programming
Object oriented vs. object based  programmingObject oriented vs. object based  programming
Object oriented vs. object based programming
 
Event-driven microservices
Event-driven microservicesEvent-driven microservices
Event-driven microservices
 
Event Driven Architecture
Event Driven ArchitectureEvent Driven Architecture
Event Driven Architecture
 
Design patterns
Design patternsDesign patterns
Design patterns
 
Deadlock Avoidance - OS
Deadlock Avoidance - OSDeadlock Avoidance - OS
Deadlock Avoidance - OS
 
Software Architecture Patterns
Software Architecture PatternsSoftware Architecture Patterns
Software Architecture Patterns
 
Design Patterns.ppt
Design Patterns.pptDesign Patterns.ppt
Design Patterns.ppt
 
Object Oriented Analysis and Design
Object Oriented Analysis and DesignObject Oriented Analysis and Design
Object Oriented Analysis and Design
 
INTRODUCTION TO UML DIAGRAMS
INTRODUCTION TO UML DIAGRAMSINTRODUCTION TO UML DIAGRAMS
INTRODUCTION TO UML DIAGRAMS
 
Object Oriented Approach for Software Development
Object Oriented Approach for Software DevelopmentObject Oriented Approach for Software Development
Object Oriented Approach for Software Development
 
CS8592-OOAD Lecture Notes Unit-3
CS8592-OOAD Lecture Notes Unit-3CS8592-OOAD Lecture Notes Unit-3
CS8592-OOAD Lecture Notes Unit-3
 
Uml deployment diagram
Uml deployment diagramUml deployment diagram
Uml deployment diagram
 

Similar to Updated: Should you be using an Event Driven Architecture

Should you be using an event driven architecture - IDA IT (short version)
Should you be using an event driven architecture - IDA IT (short version)Should you be using an event driven architecture - IDA IT (short version)
Should you be using an event driven architecture - IDA IT (short version)Jeppe Cramon
 
What 5 years of implementation microservices has taught me
What 5 years of implementation microservices has taught meWhat 5 years of implementation microservices has taught me
What 5 years of implementation microservices has taught meJeppe Cramon
 
Should you be using an event driven architecture?
Should you be using an event driven architecture?Should you be using an event driven architecture?
Should you be using an event driven architecture?Jeppe Cramon
 
The Dual write problem
The Dual write problemThe Dual write problem
The Dual write problemJeppe Cramon
 
Data Microservices with Spring Cloud
Data Microservices with Spring CloudData Microservices with Spring Cloud
Data Microservices with Spring CloudOrkhan Gasimov
 
Reactive Programming or Reactive Systems? (spoiler: both)
Reactive Programming or Reactive Systems? (spoiler: both)Reactive Programming or Reactive Systems? (spoiler: both)
Reactive Programming or Reactive Systems? (spoiler: both)Fabio Tiriticco
 
Starting Your DevOps Journey – Practical Tips for Ops
Starting Your DevOps Journey – Practical Tips for OpsStarting Your DevOps Journey – Practical Tips for Ops
Starting Your DevOps Journey – Practical Tips for OpsDynatrace
 
Glutter – A Visual Programming Environment for Complex Event Processing
Glutter – A Visual Programming Environment for Complex Event ProcessingGlutter – A Visual Programming Environment for Complex Event Processing
Glutter – A Visual Programming Environment for Complex Event Processingcscpconf
 
Top Java Performance Problems and Metrics To Check in Your Pipeline
Top Java Performance Problems and Metrics To Check in Your PipelineTop Java Performance Problems and Metrics To Check in Your Pipeline
Top Java Performance Problems and Metrics To Check in Your PipelineAndreas Grabner
 
Denver Salesforce Developer User Group dec 2016 lightning components
Denver Salesforce Developer User Group dec 2016 lightning componentsDenver Salesforce Developer User Group dec 2016 lightning components
Denver Salesforce Developer User Group dec 2016 lightning componentsMike Tetlow
 
Multithreading 101
Multithreading 101Multithreading 101
Multithreading 101Tim Penhey
 
Natural Laws of Software Performance
Natural Laws of Software PerformanceNatural Laws of Software Performance
Natural Laws of Software PerformanceGibraltar Software
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - TalkMatthias Noback
 
Eda on the azure services platform
Eda on the azure services platformEda on the azure services platform
Eda on the azure services platformYves Goeleven
 
Jeffrey Richter
Jeffrey RichterJeffrey Richter
Jeffrey RichterCodeFest
 
Develop in ludicrous mode with azure serverless
Develop in ludicrous mode with azure serverlessDevelop in ludicrous mode with azure serverless
Develop in ludicrous mode with azure serverlessLalit Kale
 
Transcend Automation's Kepware OPC Products
Transcend Automation's Kepware OPC ProductsTranscend Automation's Kepware OPC Products
Transcend Automation's Kepware OPC ProductsBaiju P.S.
 
Alternative microservices - one size doesn't fit all
Alternative microservices - one size doesn't fit allAlternative microservices - one size doesn't fit all
Alternative microservices - one size doesn't fit allJeppe Cramon
 
Building Cloud Ready Apps
Building Cloud Ready AppsBuilding Cloud Ready Apps
Building Cloud Ready AppsVMware Tanzu
 

Similar to Updated: Should you be using an Event Driven Architecture (20)

Should you be using an event driven architecture - IDA IT (short version)
Should you be using an event driven architecture - IDA IT (short version)Should you be using an event driven architecture - IDA IT (short version)
Should you be using an event driven architecture - IDA IT (short version)
 
What 5 years of implementation microservices has taught me
What 5 years of implementation microservices has taught meWhat 5 years of implementation microservices has taught me
What 5 years of implementation microservices has taught me
 
Should you be using an event driven architecture?
Should you be using an event driven architecture?Should you be using an event driven architecture?
Should you be using an event driven architecture?
 
The Dual write problem
The Dual write problemThe Dual write problem
The Dual write problem
 
Data Microservices with Spring Cloud
Data Microservices with Spring CloudData Microservices with Spring Cloud
Data Microservices with Spring Cloud
 
Reactive Programming or Reactive Systems? (spoiler: both)
Reactive Programming or Reactive Systems? (spoiler: both)Reactive Programming or Reactive Systems? (spoiler: both)
Reactive Programming or Reactive Systems? (spoiler: both)
 
Starting Your DevOps Journey – Practical Tips for Ops
Starting Your DevOps Journey – Practical Tips for OpsStarting Your DevOps Journey – Practical Tips for Ops
Starting Your DevOps Journey – Practical Tips for Ops
 
Glutter – A Visual Programming Environment for Complex Event Processing
Glutter – A Visual Programming Environment for Complex Event ProcessingGlutter – A Visual Programming Environment for Complex Event Processing
Glutter – A Visual Programming Environment for Complex Event Processing
 
Top Java Performance Problems and Metrics To Check in Your Pipeline
Top Java Performance Problems and Metrics To Check in Your PipelineTop Java Performance Problems and Metrics To Check in Your Pipeline
Top Java Performance Problems and Metrics To Check in Your Pipeline
 
Denver Salesforce Developer User Group dec 2016 lightning components
Denver Salesforce Developer User Group dec 2016 lightning componentsDenver Salesforce Developer User Group dec 2016 lightning components
Denver Salesforce Developer User Group dec 2016 lightning components
 
Multithreading 101
Multithreading 101Multithreading 101
Multithreading 101
 
Natural Laws of Software Performance
Natural Laws of Software PerformanceNatural Laws of Software Performance
Natural Laws of Software Performance
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - Talk
 
Eda on the azure services platform
Eda on the azure services platformEda on the azure services platform
Eda on the azure services platform
 
Jeffrey Richter
Jeffrey RichterJeffrey Richter
Jeffrey Richter
 
Develop in ludicrous mode with azure serverless
Develop in ludicrous mode with azure serverlessDevelop in ludicrous mode with azure serverless
Develop in ludicrous mode with azure serverless
 
Azure reactive systems
Azure reactive systemsAzure reactive systems
Azure reactive systems
 
Transcend Automation's Kepware OPC Products
Transcend Automation's Kepware OPC ProductsTranscend Automation's Kepware OPC Products
Transcend Automation's Kepware OPC Products
 
Alternative microservices - one size doesn't fit all
Alternative microservices - one size doesn't fit allAlternative microservices - one size doesn't fit all
Alternative microservices - one size doesn't fit all
 
Building Cloud Ready Apps
Building Cloud Ready AppsBuilding Cloud Ready Apps
Building Cloud Ready Apps
 

Recently uploaded

Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 

Recently uploaded (20)

Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 

Updated: Should you be using an Event Driven Architecture

  • 1. Should you be using an Event Driven Architecture? Jeppe Cramon - @jeppec Cloud Create ApS
  • 2. Or what 15+ years of distributed systems implementation has taught me Jeppe Cramon - @jeppec Cloud Create ApS
  • 3. @jeppec What mistakes can we learn from?
  • 4. @jeppec Data Storage Data Storage Data Storage Portal 1 Portal 2 Data Storage Application Process Service layer Activity/Task Service layer Data/Entity Service layer Layered SOA
  • 6. @jeppec What’s the challenge using state mutating Request/Response calls between distributed components?
  • 7. @jeppec Synchronous Request/Response lowers 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 Request/Response we can loose business data if there’s no automatic retry mechanism. Also if the operation we retry isn’t idempotent* we risk having the side effect multiple times! Client Server 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 Request Processing Duplicated Request Duplicated Response Response
  • 9. @jeppec Data Storage Data Storage Data Storage Portal 1 Portal 2 Data Storage Application Process Service layer Activity/Task Service layer Data/Entity Service layer Layered SOA
  • 10. @jeppec Be careful you don’t split the atom
  • 16. @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
  • 17. @jeppec Learnings • Task/Activity services needs to perform UPDATES across multiple data/entity services. Requires distributed transactions or fully asynchronous process management. • The more synchronous request-response remote calls you have to make the more it hurts Performance and latency. • Robustness is lower. If one data/entity services is down it can take down many other services. • Coupling is higher. Multiple task/activity services manage the same CRUD data/entity services • Cohesion is likely lower as multiple task/activity services need to replicate entity related logic
  • 18. @jeppec Conclusion Friends don’t let friends use layered SOA
  • 19. @jeppec But we surely don’t have this problem today!
  • 20. @jeppec Let’s take a concrete example From online shopping
  • 22. @jeppec Essential complexity of 2 way integration Component Warehouse Component Order Component Billing UI Send-Invoice Save-Order Sales:Save-Order() call Warehouse:Reserve-Items() call Billing:Send-Invoice() commit() Reserve- Items Local transaction between the 3 Components
  • 24. @jeppec Accidental complexity from distributed service integration Warehouse Service Order Service Billing Service UI Send- Invoice Save-Order Reserve- Items Local transaction between 2 local “Services” Remote call
  • 25. @jeppec Microservices turns a local functional call into a distributed problem
  • 26. @jeppec Dual write problem Order Service Billing Service Client Send- Invoice Save-Order Remote call causing a side effect Expected transaction boundary No simple solution (except a classic monolith) • Local-commit-then-publish • If the app crashes after local- commit then the publish operation isn’t performed • Publish-then-local-commit • If the local-commit fails then we’ve already formed the publish operation • Billing Service may receive published message BEFORE the Order Service has committed its transaction
  • 27. @jeppec Order:Save-Order() call Warehouse:Reserve-Items() call Billing:Send-Invoice() if (Billing:Call-Failed:Too-Busy?) Wait-A-While() call Billing:Send-Invoice() if (Billing:Call-Failed:Too-Busy?) Wait-A-Little-While-Longer() call Billing:Send-Invoice() if (Billing:Call-Failed:IO-Error?) Save-We-Need-Check-If-Call-Billing-Succeded-After-All AND We-Need-To-Retry call Order:Save-Order and call Warehouse:Reserve-Items AND Tell-Customer-That-This-Operation-Perhaps-Went-Well if (Billing:Call-Went-Well?) commit() Accidental complexity from distributed service integration Warehouse Service Order Service Billing Service UI Send- Invoice Save-Order Reserve- Items 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 Warehouse Billing Retail System Billing Order Warehouse Retail System Slow/unreliable network Different SLA Slow system
  • 30. @jeppec Availability goes down (without additional instances of each service) Combined availability: 97%
  • 31. @jeppec Solution Model our data and usecases, so that all our overall usecase can be turned into a set of indepent transactions that are asynchronously chained. Accept Order ? Receive Payment ? Ship Order This means that our business data must be collected in Entities, that should be limited in size (but not smaller), so that, after a transaction they are consistent (Pat Helland – Life Beyond Distributed Transactions)
  • 32. @jeppec But surely RPC is the only way to coordinate this?
  • 33. @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
  • 34. @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
  • 35. @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 a FACT, i.e., something that HAS happened”
  • 36. @jeppec Different uses for Events • Master data management and Data duplication • Data replication / migration • Notification • UI component integration • Service autonomy and Loosely coupled workflows/business processes across Services
  • 37. @jeppec This means we must switch from a Request/Response (pull) to a Reactive (push) model A change with profound consequences
  • 38. @jeppec How do we get the ball rolling now that we can’t use RPC?
  • 39. @jeppec Most applications are built with CRUD as the main paradigm Intention gets lost
  • 40. @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
  • 41. @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
  • 42. @jeppec We need to capture User Intent at the UI CRUD style Task based style Intent
  • 43. @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”
  • 44. @jeppec Commands & Events symmetry • Commands change Business Object (Entity) state which results in one or more Events being published. Command Event(s) AcceptOrder OrderAccepted ShipOrder OrderShipped AddComment CommentAdded QuarantineReview ReviewQuarantined UnquarantineReview ReviewUnquarantined Command Event
  • 45. @jeppec Command to Event public class OrderService { public void handle(AcceptOrder cmd) { orderRepository.add(new Order(cmd.orderId, cmd.orderLines)); eventBus.publish(new OrderAccepted(cmd.orderId, cmd.orderLines)); }
  • 46. @jeppec Unambigous commands? Order Id? •Is it ISO-4217 3 characters currency code (such as USD and DKK)? •Is it ISO-4217 Currency numbers (such as 840 and 208)? •Is it the currency name (such as US Dollar and Danish Krone)? •Is it the sales tax as a Percentage ? •Is it the calculated sales tax as an Amount ? •Is the key the ProductId ? •Is the value a Quantity ? AcceptOrder
  • 48. @jeppec Using Business Events to drive Business Processes Sales Service Shipping Billing Sales Customers Message Channel Online Ordering System Web Shop (Composite UI) Billing Service Warehouse Service <<External>> Order Paid MarkOrderAsPai d The sales fulfillment processing can now begin… Cmd Handler Order Paid Apply
  • 50. @jeppec We need to change focus from short technical transactions To long running business transactions supporting business processes
  • 51. @jeppec Choreographed Event Driven Processes Sales Service Order Paid Billing Service Shipping Service Warehouse Service Online Ordering System Message Channel (e.g. a Topic) Order Paid Customer Invoiced Order Paid Items Reserved Order Paid Shipping process works as a Finite State Machine (WorkFlow) handling the life cycle of Shipping and thereby forms a very central new Aggregate in the System Items Reserved
  • 52. @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
  • 54. @jeppec Equally important! Focus on identifying IF you’re within the happy path of the process From a ROI perspective many edge cases are better handled by humans than trying to automate them
  • 56. @jeppec Reactive/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 Publisher Subscriber Asynchronous Communication – A.k.a. Messaging Customer Moved Customer Moved Subscriber Customer Moved Channel
  • 57. @jeppec Smart pipes and “dumb” endpoints – (Push protocol) Service X Publisher Data and flow direction Message infrastructure (e.g. Kafka, RabbitMQ, …) Service Z Subscriber Service Y Subscriber Service M Subscriber Topic
  • 58. @jeppec Service X Publisher Service Z Consumer Service Y Consumer Service M Consumer Atom File based Feed generator Oldest Feed Older Feed Old Feed Feed Head Previous feed link HTTP Endpoint 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
  • 59. @jeppec Topic features • Decouples publisher from subscribers • Provides temporal decoupling • If a subscriber is unavailable, it will receive its messages when it comes online Topics Service - 4 Service - 1 Service - 3
  • 60. @jeppec Topic and event flow CreateOrder Sales_Service:Orders_Ac Webshop Application Customer_Service:Some_Ac OrderCreated OrderCreatedEvent Publish CreateSomeRelatedAggregate Sales_Service:OrderEvents <<Topic>> OrderCreatedEvent
  • 61. @jeppec There’s just one issue public class OrderService { public void handle(AcceptOrder cmd) { orderRepository.add(new Order(cmd.orderId, cmd.orderLines)); eventBus.publish(new OrderAccepted(cmd.orderId, cmd.orderLines)); } Dual Write problem still exists!
  • 62. @jeppec How can we solve this issue?
  • 63. @jeppec Dual write problem using Event Sourcing Order Service Billing Service Client Send- Invoice Save-Order Transaction boundary Transaction boundary Event Store • Requires only local transactions • Natively event driven: The Service consumes and produces events • Proven Audit Trail • Flexible and adaptable • Captures business intentions as events • Requires idempotent operations
  • 64. @jeppec Event Sourcing Business-Objects/Aggregates track their own Domain Events and derive their state from said Events Time 07:39 Time 07:40 Time 07:41 Time 07:45 Time 07:46 Time 07:50
  • 65. @jeppec Typed Events public class OrderAdded extends Event<OrderId> { public final CustomerId orderingCustomerId; public final long orderNumber; public OrderAdded(OrderId orderId, CustomerId orderingCustomerId, long orderNumber) { aggregateId(orderId); this.orderingCustomerId = orderingCustomerId; this.orderNumber = orderNumber; } } public class ProductAddedToOrder extends Event<OrderId> { public final ProductId productId; public final int quantity; public ProductAddedToOrder(ProductId productId, int quantity) { aggregateId(orderId); this.productId = productId; this.quantity = quantity; } }
  • 66. CRUD There’s no reason to delete data or update data. We only need to append and read Events from our Event Store
  • 67. @jeppec Full CQRS with EventSourcing UI Domain Event Store Commands – Change data Commands Events UI Data Queries – Ask for data Events Query Build Our single source of truth SQL DB Graph DB Document DB
  • 68. @jeppec Typed Aggregate public class Order extends AggregateRoot<OrderId, Order> { private Map<ProductId, Integer> productAndQuantity; private boolean accepted; public Order(OrderId orderId, CustomerId orderingCustomerId, int orderNumber) { FailFast.requireNonNull(orderId, "You must provide a orderId"); FailFast.requireNonNull(orderingCustomerId, "You must provide an orderingCustomerId"); apply(new OrderAdded(orderId, orderingCustomerId, orderNumber)); } public void addProduct(ProductId productId, int quantity) { FailFast.requireNonNull(productId, "You must provide a productId"); if (accepted) { throw new IllegalStateException("Order is already accepted"); } apply(new ProductAddedToOrder(productId, quantity)); }
  • 69. @jeppec Event Replaying Type Aggregate Identifier GlobalOrder Sequence Number Timestamp Event Identifier EventType SerializedEvent Order 14237 100 0 2014-01-06 7:39 {Guid-1} OrderCreated <serialized event>… Order 14237 101 1 2014-01-06 7:40 {Guid-2} ProductAdded <serialized event>… Order 14237 102 2 2014-01-06 7:41 {Guid-3} ProductAdded <serialized event>… Order 14237 103 3 2014-01-06 7:45 {Guid-4} ProductRemoved <serialized event>… Order 14237 104 4 2014-01-06 7:46 {Guid-5} ProductAdded <serialized event>… Order 14237 105 5 2014-01-06 7:50 {Guid-6} OrderAccepted <serialized event>… Order Accepted: true Orderline Orderline
  • 70. @jeppec Aggregate replay public class Order extends AggregateRoot<OrderId, Order> { private Map<ProductId, Integer> productAndQuantity; private boolean accepted; public void accept() { if (accepted) { return; } apply(new OrderAccepted()); } @Override protected void applyEventToTheAggregate(Event<OrderId> event) { if (event instanceof OrderAdded e) { productAndQuantity = HashMap.empty(); } else if (event instanceof ProductAddedToOrder e) { Option<Integer> existingQuantity = productAndQuantity.get(e.productId); productAndQuantity = productAndQuantity.put(e.productId, e.quantity + existingQuantity.getOrElse(0)); } else if (event instanceof ProductOrderQuantityAdjusted e) { productAndQuantity = productAndQuantity.put(e.productId, e.newQuantity); } else if (event instanceof ProductRemovedFromOrder e) { productAndQuantity = productAndQuantity.remove(e.productId); } else if (event instanceof OrderAccepted) { accepted = true; } }
  • 71. @jeppec Topic features But how do we handle: • Coding errors in Subscribers? • New Subscribers that didn’t exist when the events were originally published? Topics Service - 4 Service - 1 Service - 3
  • 72. @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.
  • 73. @jeppec Client handled subscriptions RSocketEvent StreamSubscription Local storage EventStore RSocketEvent StreamSubscription Local storage EventStreamSubscription Message EventStreamSubscription Message EventStoreEventStreamPublisher EventStoreEventStreamPublisher Event Event Event Event Supports Single Instance Subscriber, which ensures that only one instance of Subscriber B has an active subscription. Other instances of the same subscriber are hot-standby <<Topic Subscriber>> Customer_Service:Some_Ac:OrderEvents <<Topic Publisher>> Sales_Service:OrderEvents RSocketServer tcp://subscribe-event-stream A B Subscriber B RSocket Request/Stream Event-Stream Subscriber A RSocket Request/Stream Event-Stream Flux<PersistedEvent> eventStream(long fromInclusiveGlobalOrd Option<String> subscripti
  • 74. @jeppec ReactiveBus Pub/Sub JdbcEventStores eventStores = …. var customerAggregateType = AggregateType.from("Customer", CustomerTestEvents.CustomerId.class); var customerEventStore = eventStores.getEventStoreFor(customerAggregateType); var streamName = EventStreamName.from("CustomersStream"); reactiveBus.addEventStreamPublisher(new EventStoreEventStreamPublisher(streamName, customerEventStore, unitOfWorkFactory)); Publisher: reactiveBus.subscribeToEventStream( SubscriberId.from(”SalesService->CustomerEvents"), EventStreamName.from("CustomersStream"), EventStreamSubscriptionParameters.parameters(GlobalOrderSubscribeFromToken.fromStartOfStream())) .doOnNext(payload -> { System.out.println(”Received: " + e.payload.getClass() + "@" + e.globalOrder); }).subscribe(); Subscriber:
  • 75. @jeppec Pub/Sub – Subscriber event handling reactiveBus.subscribeToEventStream(SubscriberId.from(”SalesService->OrderEvents"), EventStreamName.from(”OrdersStream"), EventStreamSubscriptionParameters.parameters(GlobalOrderSubscribeFromToken.fromStartOfStream .doOnNext(payload -> { if (event instanceof OrderAdded e) { .. = e.orderNumber; } else if (event instanceof ProductAddedToOrder e) { … = e.productId; } else if (event instanceof OrderAccepted) { …accepted = true; } ).subscribe();
  • 76. @jeppec Pub/Sub – Subscriber event handling @EventHandler private void handle(OrderAdded e, EventMessage message) { …. } @EventHandler private void handle(ProductAddedToOrder e) { .… } @EventHandler private void handle(OrderAccepted e) { …. }
  • 78. @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>
  • 79. @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" } ] }
  • 80. @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:
  • 81. @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
  • 82. @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
  • 83. @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
  • 84. @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
  • 85. @jeppec There are only two hard problems in distributed systems 2. Exactly Once Delivery 1. Guaranteed Order of Messages 2. Exactly Once Delivery @mathiasverraes
  • 86. @jeppec Things are not quite the same In a distributed system the order in which messages arrive is not guaranteed In a distributed systems message delivery can and will fail! Messages can be delivered according to these guarantees: • At Most Once – If you don’t care about loosing messages • Page visits • Ad views • 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!
  • 87. @jeppec Message Handling public class OrderShippingProcess extends MessageHandler { @MessageHandler private void on(OrderPaid orderPaid, ItemsReserved itemsReserved) { ShippingDetails shippingDetails = getShippingDetailsForOrder(orderPaid.orderId); …. printShippingLabel(orderPaid.orderId, shippingDetails.address); } … } Must also be idempotent
  • 88. @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
  • 89. @jeppec Event Monitoring Command, Document and Event messages all contain the following data: • Timestamp • Unique message Id • Correlation Id • Caused by Event 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.
  • 91. @jeppec When to prefer a Request/Response (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 event choreography can 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 (e.g. Accept Order)
  • 92. @jeppec How to design services that are loosely coupled?
  • 93. @jeppec "I consider 'getting the boundaries right' the single design decision with the most significant impact over the entire life of a software project." @ziobrando
  • 95. @jeppec This highly depends on • How likely are things to change • And what parts that change together
  • 97. @jeppec Result is often fragmented domain logic Focus on Nouns (Entities) and retrofit Verbs later
  • 99. @jeppec If we primarily model around nouns/entities we can easily violate the SRP Where a change to requirements is likely to require changes to multiple entity classes
  • 100. @jeppec Business introduces new rule Product price depends on Customer Status
  • 104. @jeppec When discussing use cases with Business Experts
  • 105. @jeppec and what fields that are separate
  • 108. @jeppec But don’t name the piles before you know what they are This avoids cognitive bias!
  • 109. @jeppec Give the piles made up names, such as colors
  • 110. @jeppec What are these problem domain piles?
  • 112. @jeppec If we align the problem domain with the solution domain Bounded Context 1 Bounded Context 3 Bounded Context 2 UI BL DAO UI BL DAO UI BL DAO Vertical coupling is unavoidable We want to avoid horizontal coupling
  • 113. @jeppec What are the solution domain piles? 113
  • 114. @jeppec A Service is • The technical authority for a given bounded context • It is the owner of all the data and business rules that support this bounded context – everywhere • It forms a single source of truth for that bounded context http://udidahan.com/2010/11/15/the-known-unknowns-of-soa/
  • 115. @jeppec Be aware of Conways Law “organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations” Teams are typically aligned with Systems and NOT with Services as they should Said another way: How you organize yourself, determines your architecture
  • 116. @jeppec Business Capability alignment “The advantage of business capabilities is their remarkable level of stability. If we take a typical insurance organisation, it will likely have sales, marketing, policy administration, claims management, risk assessment, billing, payments, customer service, human resource management, rate management, document management, channel management, commissions management, compliance, IT support and human task management capabilities. In fact, any insurance organisation will very likely have many of these capabilities.” See http://bill-poole.blogspot.dk/2008/07/business-capabilities.html
  • 117. @jeppec Business – IT alignment • We want the Business and IT to speak the same Ubiquitous language • Want want our architecture to be aligned with the business capabilities • Because these capabilities are stable
  • 118. @jeppec Many perspectives on data Online Retail System Product Unit Price Promotional Price Promotion End Date Stock Keeping Unit (SKU) Quantity On Hand (QOH) Location Code Price Quantity Ordered Name The lifecycle of the data is VERY important! Customer Pricing Inventory Sales Management Reporting
  • 119. @jeppec Smaller models & clear data ownership Retail System Pricing Product ProductID Unit Price Promotional Price … Pricing Inventory Product ProductID SKU QOH Location Code … Inventory Sales Product ProductID Name Description Quantity Ordered … Sales Shared Entity identity DDD: Bounded Context Business Capability Service
  • 120. @jeppec Bounded Contexts and Aggregates Sales Product Customer customerId … Order orderId customerId … OrderLine orderId productId quantity timestamp priceId ProductCategory productCategoryId … Pricing Product productId productCategoryId name tag ... Product-Price priceId productId normalPrice discountPeriods …
  • 121. @jeppec Using Business Events to drive Business Processes Sales Service Shipping Billing Sales Customers Message Channel Online Ordering System Web Shop (Composite UI) Billing Service Shipping Service <<External>> Order Accepted AcceptOrder The sales fulfillment processing can now begin… Cmd Handler Order Accepted Apply
  • 123. @jeppec Microservices promise a solution to our problem Monolith Microservice Microservice Microservice Microservice Microservice Microservice Microservice
  • 124. @jeppec There’s never time to do it right But there’s always time to do it over 124
  • 125. @jeppec Microservices is an architectural style 125
  • 127. @jeppec Service and deployment • A Service represents a logical responsibility boundary • Logical responsibility and physical deployment of a Service DOES NOT have to be 1-to-1 • It’s too constraining • We need more degrees of freedom • Philippe Krutchen 4+1 views of architecture: Logical and Physical designs should be independent of each other A service needs to be deployed everywhere its data is needed
  • 129. @jeppec Service Microservices 1..* Is implemented by A Service is the technical authority of a specific Bounded-Context/Business Capability e.g. Sales, Shipping, Billing Service vs Microservices
  • 130. @jeppec Service Microservices 1..* Is implemented by Service vs Microservices Microservices are a division of Services along Transactional boundaries (a transaction stays within the boundary of a Microservice) Microservices are the individual deployable units of a Service with their own Endpoints. Could e.g. be the split between Read and Write models (CQRS) - each would be their own Microservices
  • 131. @jeppec A Service represents a logical boundary 131 Service Microservice Microservice Microservice Microservice
  • 132. @jeppec Services are the corner stone • We talk in terms of Services capabilities and the processes/use-cases they support • Microservices are an implementation detail • They are much less stable (which is a good thing – it means they’re easier to replace)
  • 133. @jeppec Service deployment • Many services can be deployed to the same physical server • Many services can be deployed in the same application • Application boundary is a Process boundary which is a physical boundary • A Service is a logical boundary • Service deployment is not restricted to tiers either • Part of service A and B can be deployed to the Web tier • Another part of Service A and B can be deployed to the backend/app-service tier of the same application • The same service can be deployed to multiple tiers / multiple applications • ie. applications and services are not the same and does not share the same boundaries • Multiple services can be “deployed” to the same UI page (service mashup)
  • 134. @jeppec What about Security Is Security a Service? • If it’s technical YES • Example: Authentication & Authorization • If it’s a business related, i.e. Business rule, – NO • Then it belongs inside the Service responsible for this business capability • Example: Who’s allowed to authorize large transfers or who’s allowed to reimburse the customer
  • 135. @jeppec How do we bring things together for our users without introducing unnecessary coupling?
  • 136. @jeppec Let’s look at Applications
  • 137. @jeppec iOS Home Banking Customer information Legal and contract information Accounts
  • 138. @jeppec iOS Home banking Customer information Legal and contract information Accounts Credit card Mortgage loans Web banking portal Bank Back-office application
  • 139. @jeppec Let’s assume we have these services Currency Service Customer Service Identity Management Service Sales Service Inventory Service Products Service IT Operations Shipping Service Web Shop
  • 140. @jeppec Back-end for Front-end? Client Remote Facade DTOs Identity Management Service Customer Service Products Service Sales Service Inventory Service Shipping Service Currency Service IT Operations
  • 141. @jeppec Service A Service B Service C IT-OPS Web shop Warehouse Back office App logic (Layered, CQRS,…) Warehouse Storage UI Components A Services owns its UI Components
  • 144. @jeppec Composite page example Page Context: {id: ISBN-10 0-321-83457-7 } Images Books Reviews Pricing Inventory OthersAlsoBought Pricing Reviews Books Images Books
  • 145. @jeppec A Service represents a logical boundary Service Microservice Autonomous Component Adapter UI component
  • 146. @jeppec An Application is the plate where Components are co-deployed Sales service components Inventory service components …
  • 147. @jeppec An UI is composed of widgets from different services
  • 148. @jeppec Service Widget Service Widget Page Service Widget Service Widget Service Widget • Overall structure of the page is “owned” by the application. • Each service widget is independent Composite page layout Service Widget Service Widget Service Widget Service Widget
  • 149. @jeppec https://our.micro-cool.bank-portal Customer Name: Peter Hansen Address: Some Road 1 Some Zip Some City Customer relations Spouse: Mette Hansen Children: Jacob Hansen Ditte Hansen Overview Page (owned by the application) <<UI Component>> Customer Details Component <<UI Component>> Customer Relations Component UI layer Backend layer Customer Details Microservice Customer Relations Microservice HTTPS HTTPS
  • 151. @jeppec Page Rendering Example Page Ctrl Sales Service UI Broker Customer Service Pricing Service Product Service Page Widget Ctrl Widget Ctrl Widget Ctrl Widget Ctrl Widget Ctrl Widget Ctrl Widget Ctrl Widget Ctrl 1. Backend API Backend API Backend API Backend API 2. 3. 4. 5. 5. 6. 7. 7. 7. 7. 5. 8. 8. 8. 8.
  • 152. @jeppec Self Contained Systems LINKS / REDIRECTIONS UI INCLUSION https://scs-architecture.org
  • 155. @jeppec Dynamic Inclusion Content served by another application within a self contained system
  • 156. Thanks :) Blog: https://cramonblog.wordpress.com/ Homepage: http://cloudcreate.dk/ Twitter: @jeppec