SlideShare une entreprise Scribd logo
1  sur  69
Télécharger pour lire hors ligne
Refactoring to a

System of Systems
/ olivergierkeOliver Gierke ƀ ogierke@pivotal.io
Of monoliths, microservices and everything in between…
2
3
Monolith(aka. Big Ball of Mud)
Microlith(the Careless Microservice)
Modulith
System

of

Systems
1
2
3
4
Messaging
REST
6
5
What are typical
Bounded Context
interactions in a
monolithic application?
“
4
What happens if these
patterns are translated

1:1 into a distributed
system?
“
5
Can we build a

better monolith

in the first place?
“
6
How to translate that
new approach into a
distributed system?
“
7
The Domain
8
9
Orders
Catalog
Inventory
Products
Product details
Prices
Order

Line items
Stock
Inventory items
When a product is added
to the catalog, the
inventory needs to
initialize its stock.
“
10
When an order is
completed, inventory
shall update its stock

for all line items.
“
11
What do we want to focus on?
• What are commonly chosen design patterns and strategies?
• How do Bounded Contexts interact with each other?
• What types of consistency do we deal with?
• How do the systems behave in erroneous situations?
• How do the different architectures support independent evolvability?
12
Sample code
https://github.com/olivergierke/sos
13
A couple of warnings…
The sample code is not a cookie cutter recipe of how to build things
The sample code is supposed to focus on showing the interaction model between Bounded Contexts,
how to model aggregates and strive for immutability as much as possible. However, to not complicate
the matter, certain aspects have been kept intentionally simple to avoid further complexity to blur the
focus of the samples:
• Not all domain primitives are fully modeled
• Monetary amounts are not modeled as such, but definitely should in real world projects.
• Quantities are modeled as plain long but also should get their own value types.
• Most projects use JPA for persistence. This requires us to have default constructors and some
degrees of mutability in domain types.
• Remote interaction is not fully implemented (not guarded against systems being unavailable etc.)
14
Ɨ The Monolith
15
16
Orders Catalog
Inventory
ɧ

Product


Order
Line

Items


Inventory

Item
Active invocation
Bounded Context
Legend
Aggregate
The Monolith – Design Decisions
+ Bounded Contexts reflect into packages
A (hopefully not very) typical Spring Boot based Java web application. We have packages for individual
Bounded Contexts which allows us to easily monitor the dependencies to not introduce cycles.
+ / − Domain classes reference each other even across Bounded Contexts
JPA creates incentives to use references to other domain types. This makes the code working with
these types very simple at a quick glance: just call an accessor to refer to a related entity. However, this
also has significant downsides:
• The „domain model“ is a giant sea of entities – this usually causes problems with the persistence layer
with transitive related entities as it’s easy to accidentally load huge parts of the database into memory.
The code is completely missing the notion of an aggregate that defines consistency boundaries.
• The scope of a transaction grows over time – Transactions can easily be defined using Spring’s
@Transactional on a service. It’s also very convenient add more and more calls — and ultimately
changes to entities — which blur the focus of the business transaction and making more likely to fail
for unrelated reasons.
17
The Monolith – Design Decisions
+ Inter-context interaction is process local
As the system is running as a single process, the interaction between Bounded Contexts is performant
and very simple. We don’t need any kind of object serialization and each call either succeeds or results
in an exception. APIs can be refactored easily as IDEs can tweak calling and called code at the same
time.
− Very procedural implementation in order management
The design of OrderManager.addToOrder(…) treats domain types as pure data containers. It accesses
internals of Order, applies some logic to LineItems and manipulates the Order state externally. However,
we can find first attempts of more domain driven methods in LineItem.increaseQuantityBy(…).
18
The Monolith – Design Decisions
− Order management actively invokes code in inventory context
With the current design, services from different Bounded Contexts usually invoke each other directly.
This often stems from the fact that it’s just terribly convenient to add a reference to a different
managed bean via Dependency Injection and call that bean’s methods. This easily creates cyclic
dependencies as the invoking code needs to know about the invoked code which in turn usually will
receive types owned by the caller. E.g. OrderManagement knows about the Inventory and the Inventory
accepts an Order.
A side-effect of this is that the scope of the transaction all of a sudden starts to spread multiple
aggregates, even across contexts. This might sound convenient in the first place but with the application
growing this might cause problems as supporting functionality might start interfering with the core
business logic, causing transaction rollbacks etc.
19
The Monolith – Consequences
− Service components become centers of gravity
Components of the system that are hotspots in business relevance („order completed“) usually become
centers of dependencies and dissolve into god classes that refer to a lot of components of other
Bounded Contexts. The OrderManagement’s completeOrder(…) method is a good example for that as will
have to be touched to invoke other code for every feature that’s tied to that business action.
− Adding a new feature requires different parts of the system to be touched
A very typical smell in that kind of design is that new features will require existing code to be touched
that should not be needed. Imagine we’re supposed to introduce a rewards program that calculates
bonus points for completed orders. Even if a dedicated team implements that feature in a completely
separate package, the OrderManagement will eventually have to be touched to invoke the new
functionality.
20
The Monolith – Consequences
+ Easy to refactor
The direct type dependencies allows the IDE to simplify refactorings. We just have to execute them and
calling and called code gets updated. We cannot accidentally break involved third parties as there are
none. Especially in scenarios where there’s little knowledge about the domain, this can be very
advantageous. The interesting fact to notice here is that we have strong coupling but still can refactor
and evolve relatively rapidly. This is driven by the locality of the changes.
+ / − Strong consistency
JPA creates incentives to use references to other domain types. This usually leads to code that
attempts to change the state of a lot of different entities. In conjunction with @Transactional it’s very
easy to create huge chunks of changes that spread a lot of entities, which seems simple and easy in the
first place. The lack of focus on aggregates leads to a lack of structure that significantly serves the
erosion of architecture.
21
The Monolith – Consequences
− Order management becomes central hub for new features
The lack of structure and demarcation of different parts usually manifests itself in code that
implements key business cases to get bloated over time as a lot of auxiliary functionality being attached
to it. In most cases it doesn’t take more than an additional dependency to be declared for injection and
the container will hand it into the component. That makes up a convenient development experience but
also bears the risk of overloading individual components with too many responsibilities.
22
The Microlith
23
Ɨ
Ɨ
Ɨ
24
Orders
Catalog
Inventory


HTTP

POST


HTTP

POST
Update

inventory
Initialize

stock
Active invocation
System
Legend
The Microlith – Problems
+ / − Simple, local transactional consistency is gone
The business transaction that previously could use strong consistency is now spread across multiple
systems which means we have two options:
• Stick to strong consistency and use XA transactions and 2PC
• „Starbucks doesn't use two-phase commit“ – Gregor Hohpe, 2004
• Switch to embracing eventual consistency and idempotent, compensating actions
− Interaction patterns of the Monolith translated into a distributed system
What had been a local method invocation now involves network communication, serialization etc.
usually backed by very RPC-ish HTTP interaction. The newly introduced problems usually solved by
adding more technology to the picture to implement well-known patterns of remote systems
interaction, like bulkheads, retries, fallbacks etc. Typically found technology is Netflix Hystrix,
Resilience4j, Spring Cloud modules etc.
25
The Microlith – Problems
− Remote calls executed while serving user request
As this interaction pattern usually accumulates a lot of latency (especially if the called system calls other
systems again) the execution module needs to switch to asynchronous executions and reactive
programming, further complicating the picture.
− Individual systems need to know the systems they want to invoke
While the location of the system to be called can be abstracted using DNS and service discovery,
systems following that architectural style tend to ignore hypermedia and hard-code resource locations
to interact with into client implementations. This creates a rather strong coupling as it limits the servers
ability to change it’s APIs.
− Running the system requires upstream systems to be available or mocked
As the invocation of other systems is a fundamental part of the execution of main business logic, these
upstream systems need to be available when a system is run. This complicates testing as these systems
usually need to be stubbed or mocked.
26
The Microlith – Problems
− Strong focus on API contracts
As the interaction pattern between the systems is a 1:1 copy of the one practiced in the monolith,
usually the same API definition techniques and practices are used. This usually oversees that this creates
the same strong coupling between the communicating parties and evolvability severely suffering as the
communicating parties are located at much greater distance than in the monolith.
For reference, see Jim Weirich’s talk on Connascence:
„As the distance between software elements increases, use weaker forms of connascence.“
Ignoring that rule produces tightly coupled distributed systems preventing independent evolution of
the individual systems, a core goal of a microservice architecture in the first place.
27
Ƙ The Modulith
28
29
Orders
Catalog
Inventory
Order

completed
ƻ

Event Product

added
Out of

stock
ƻ

Event
ƻ

EventEvents published to
Bounded Context
Legend
The Modulith – Fundamental differences
+ Focus of domain logic implementation has moved to the aggregate
The aggregates become the focus point of domain logic. Key state transitions are implemented as
methods on the aggregate. Some of them register even dedicated events.
+ Integration of Bounded Contexts is implemented using events
The events produced by an aggregate are automatically published on repository interaction via Spring’s
application event mechanism. This allows to define event listeners in other interested Bounded
Contexts.
+ Invert invocation dependencies between Bounded Contexts
Previously code within a Bounded Context actively reached out to other contexts and invoked
operations that change state within that context. These state transitions can now be triggered by
consuming events published by other Bounded Contexts.
30
ɐ Detour:
Events and Consistency
31
32
@EventListener
@EventListener
…
@TransactionalEventListener
@TransactionalEventListener
…
@Transactional
ƻ

Event
ƻ

Event
Commit
1
2
3
4
5
6
7
8
Consistency boundary
Spring bean
Legend
Application events in a Spring application
1. We enter a transactional method
Business code is executed and might trigger state changes on aggregates.
2. That transactional method produces application events
In case the business code produces application events, standard events are published directly. For each
transactional event listener registered a transaction synchronization is registered, so that the event will
eventually be published on transaction completion (by default on transaction commit).
3. Event listeners are triggered
By default, event listeners are synchronously invoked, which means they participate in the currently
running transactions. This allows listeners to abort the overall transaction and ensure strong
consistency. Alternatively, listeners can be executed asynchronously using @Async. They then have to
take care of their transactional semantics themselves and errors will not break the original transaction.
33
Application events in a Spring application
4. Service execution proceeds once event delivery is completed
Once all standard event listeners have been invoked, the business logic is executed further. More events
can be published, further state changes can be created.
5. The transaction finishes
Once the transactional method is done, the transaction is completed. Usually all pending changes
(created by the main business code or the synchronous event listeners) are written to the database. In
case inconsistencies or connection problems, the transaction rolls back.
6. Transactional event listeners are triggered
Listeners annotated with @TransactionalEventListener are triggered when the transaction commits,
which means they can rely on the business operation the event has been triggered from having
succeeded. This allows the listeners to read committed data. Listeners can be invoked asynchronously
using @Async in case the functionality to be invoked might be long-running (e.g. sending an email).
34
ɐ Detour:
Application Events

with Spring (Data)
35
Application events with Spring (Data)
• Powerful mechanism to publish events in Spring applications
• Application event – either a general object or extending ApplicationEvent
• ApplicationEventPublisher – injectable to manually invoke event publication
• Spring Data event support
• Spring Data’s focus: aggregates and repositories
• Domain-Driven Design aggregates produce application events
• AbstractAggregateRoot<T> – base class to easily capture events and get them published on
CrudRepository.save(…) invocations.
• No dependency to infrastructure APIs
• Integration with messaging technology via event listeners
36
37
// Super class contains methods with
// @DomainEvents und @AfterDomainEventPublication
class Order extends AbstractAggregateRoot<Order> {
Order complete() {
registerEvent(OrderCompletedEvent.of(this));
return this;
}
}
38
@Component
class OrderManagement {
private final OrderRepository orders;
@Transactional
void completeOrder(Order order) {
orders.save(order.complete());
}
}
Application events – Error Scenarios
A synchronous event listener fails
In case a normal event listener fails the entire transaction will roll back. This enables strong consistency
between the event producer and the listeners registered but also bears the risk of supporting
functionality interfering with the primary one, causing the latter to fail for less important reasons. The
tradeoff here could be to move to a transactional event listener and embrace eventual consistency.
An asynchronous event listener fails
The event is lost but the primary functionality can still succeed as the event is handled in a separate
thread. Retry mechanisms can (should?) be deployed in case some form of recovery is needed.
39
Application events – Error Scenarios
The transactional service execution fails
Assuming the event listeners also execute transactional logic, the local transaction is rolled back and the
system is still in a strongly consistent state. Transactional event listeners are not invoked in the first
place.
A transactional event listener fails
In case a transactional event lister fails or the application crashes while transactional event listeners are
executed, the event is lost and functionality might not have been invoked.
40
ɐ Detour:
Event Publication Registry
41
42
@TransactionalEventListener
@TransactionalEventListener
…
ƻ

Event
@TransactionalEventListener
…
@TransactionalEventListener
…
Transaction Commit
42
@TransactionalEventListener
@TransactionalEventListener
…
ƻ

Event
@TransactionalEventListener
…
@TransactionalEventListener
…
Transaction Commit
Event Publication Registry
1. Write application event publication log for transactional listeners
On application event publication a log entry is written for every event and transactional event listener
interested in it. That way, the transaction remembers which events have to be properly handled and in
case listener invocations fail or the application crashes events can be re-published.
2. Transaction listeners are decorated to register successful completion
Transactional event listeners are decorated with an interceptor that marks the log entry for the listener
invocation on successful listener completion. When all listeners were handled, the log only contains
publication logs for the ones that failed.
3. Incomplete publications can be retried
Either periodically or during application restarts.
43
Sample code
https://github.com/olivergierke/spring-domain-events
44
Summary
Events for Bounded Context interaction
Spring’s application events are a very light-weight way to implement those domain events. Spring Data
helps to easily expose them from aggregate roots. The overall pattern allows loosely coupled
interaction between Bounded Contexts so that the system can be extended and evolved easily.
Externalize events if needed
Depending on the integration mechanism that’s been selected we can now write separate components
to translate those JVM internal events into the technology of choice (JMS, AMQP, Kafka) to notify third-
party systems.
45
The System of Systems
46
Ɨ ƗƗ
Integration options
47
Messaging REST
What is needed for a
single system to run?
“
48
What happens if a
system goes down?
“
49
What happens if a

failed system comes

up again?
“
50
What happens if a new
system enters the scene?
“
51
The System of Systems
52
Ɨ ƗƗ
Messaging
53
Orders Catalog
Inventory
ƻ

Order

completed
Kafka
ƻ

Product

added
ƻ

Out of

stock
Order completed
Product added
Product added
Demo
• Start broker
• Start individual services
• Show HAL browser, APIs
• Show systems interaction
• Add Product -> show InventoryItem and ProductInfo being created
• Trigger shipment -> show amount in InventoryItem increasing
• Trigger order creation -> show amount in InventoryItem decreasing
• Trigger further order creations -> show Inventory publishing OutOfStock event
54
Key characteristics
Integration via a central broker
• Shared infrastructure
• Some business decisions (TTL of events) in shared component
• Broker knows about all messages of all systems (potentially forever)
• Technology built for scale
Events published as messages
55
Key characteristics
Different broker technologies have different replay characteristics
• JMS — durable subscription (requires initial registration with the broker)
• AMQP — fanout exchanges (requires initial registration with the broker)
• Kafka — topics / partitions, log compaction
Coupling via message serialization format
56
Key characteristics
Different broker technologies have different replay characteristics
• JMS — durable subscription (requires initial registration with the broker)
• AMQP — fanout exchanges (requires initial registration with the broker)
• Kafka — topics / partitions, log compaction
Coupling via message serialization format
Transactional semantics
• 2PC or compensating messages
56
The System of Systems
57
Ɨ ƗƗ
REST
58
Orders Catalog
Inventory
ƻ

Order

completed


API
ƻ

Product

added
ƻ

Out of

stock


API


API
Event publication via HTTP resources
HTTP resources for events
Events are considered application state and expose HTTP resources for client consumption
Typical design aspects
• Collection resource filterable by:
• Event type — as a replacement for topics
• Publication date after — to see event
• Pagination — to allow clients to define the pace at which they want to see events
• Caching & conditional requests — to avoid load on the application
Typical media types used
• Atom feeds (XML)
• HAL
• Collection/JSON
59
Event consumption via polling
Clients regularly poll event resources
Clients interested in events of other systems discover producing system and events resource
Client under control of the consistency gap
• Trade polling frequency over
Typical design aspects
• Low coupling through service- and resource discovery
• Focus on link relations and URI templates, http://…/events{?since,type}
• Polling frequency as key actuator for integration
• Back-off strategies if the remote system is unavailable
• Purposely bigger consistency window in case of heavy load
60
Key characteristics
+ No (additional) centralized infrastructure component needed
We don’t need to connect to a central, shared resource to run the system. This is eases testing. Also,
HTTP interaction is usually well understood and already used in the system anyway. A lot of HTTP based
technology available to help constructing the overall system (caches, proxies etc.)
+ Event publication is part of a local transaction
Event publication does not involve interaction with an additional resource. It’s basically an additional
row in the database table.
+ Publishing systems controls event lifecycle / security
The publishing system completely controls the lifecycle of the events published. Changes in e.g. the TTL
do not involve reconfiguration of infrastructure. Security implications (who is allowed to see which
events?) are handled on the API level.
61
Key characteristics
+ Events stay with the publishing system
As events are application state, there’s no single component in the overall system that can get flooded
by one system potentially flooding the overall system with events.
− Bigger consistency gap because of polling
The pull-model of course creates a bigger consistency gap than message listener invocation. As systems
have to cope with eventual consistency anyway, this might not be a big problem.
− Doesn’t scale too well for high-volume event publications
In case of a lot of events per single aggregate, the aforementioned consistency gap might be
unacceptable.
62
The System of Systems
63
Ɨ ƗƗ
Summary
Key aspects
• Limited remote interaction
• „I like monoliths so much that I’d like to build many of them.“ — Stefan Tilkov
• Separation of user requests and state synchronization
• Data duplication to avoid the need to synchronously reach out to 3rd-party systems
• Implicit anti-corruption layer to map models
64
Resources
65
Resources
Self-Contained Systems
• https://scs-architecture.org
Connascence
• https://en.wikipedia.org/wiki/Connascence_(computer_programming)
The Grand Unified Theory – Jim Weirich, 2009
• https://www.youtube.com/watch?v=NLT7Qcn_PmI
Software Architecture for Developers – Simon Brown
• https://leanpub.com/b/software-architecture
Starbucks doesn’t use two-phase commit – Gregor Hohpe, 2004
• http://www.enterpriseintegrationpatterns.com/ramblings/18_starbucks.html
66
Resources – Domain-Driven Design
Domain-Driven Design – Eric Evans, 2003
• https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215
Implementing Domain-Driven Design – Vaughn Vernon, 2013
• https://www.amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577/
Domain-Driven Design Distilled – Vaughn Vernon, 2016
• https://www.amazon.com/Domain-Driven-Design-Distilled-Vaughn-Vernon/dp/0134434420
• https://www.amazon.de/Domain-Driven-Design-kompakt-Vaughn-Vernon/dp/3864904390
67

Contenu connexe

Similaire à Refactoring to a system of systems

Secret Twists to Efficiently Develop Reactive Software Systems
Secret Twists to Efficiently Develop Reactive Software SystemsSecret Twists to Efficiently Develop Reactive Software Systems
Secret Twists to Efficiently Develop Reactive Software SystemsBart Jonkers
 
How to Overcome Data Challenges When Refactoring Monoliths to Microservices
How to Overcome Data Challenges When Refactoring Monoliths to MicroservicesHow to Overcome Data Challenges When Refactoring Monoliths to Microservices
How to Overcome Data Challenges When Refactoring Monoliths to MicroservicesVMware Tanzu
 
Software Architecture and Architectors: useless VS valuable
Software Architecture and Architectors: useless VS valuableSoftware Architecture and Architectors: useless VS valuable
Software Architecture and Architectors: useless VS valuableComsysto Reply GmbH
 
The Clean Architecture
The Clean ArchitectureThe Clean Architecture
The Clean ArchitectureDmytro Turskyi
 
API-driven Legacy Migration: Results from Project Winterfell
API-driven Legacy Migration: Results from Project WinterfellAPI-driven Legacy Migration: Results from Project Winterfell
API-driven Legacy Migration: Results from Project WinterfellKeith McFarlane
 
Microservices architecture
Microservices architectureMicroservices architecture
Microservices architectureFaren faren
 
Viktor Turskyi "Effective NodeJS Application Development"
Viktor Turskyi "Effective NodeJS Application Development"Viktor Turskyi "Effective NodeJS Application Development"
Viktor Turskyi "Effective NodeJS Application Development"Fwdays
 
Infinit's Next Generation Key-value Store - Julien Quintard and Quentin Hocqu...
Infinit's Next Generation Key-value Store - Julien Quintard and Quentin Hocqu...Infinit's Next Generation Key-value Store - Julien Quintard and Quentin Hocqu...
Infinit's Next Generation Key-value Store - Julien Quintard and Quentin Hocqu...Docker, Inc.
 
netsuite-integration-whitepaper
netsuite-integration-whitepapernetsuite-integration-whitepaper
netsuite-integration-whitepaperOlivier Gagnon
 
Micro-services architecture
Micro-services architectureMicro-services architecture
Micro-services architectureFarwa Ansari
 
Git & dev ops come together, right now!
Git & dev ops come together, right now!Git & dev ops come together, right now!
Git & dev ops come together, right now!rhirschfeld
 
Microservices for performance - GOTO Chicago 2016
Microservices for performance - GOTO Chicago 2016Microservices for performance - GOTO Chicago 2016
Microservices for performance - GOTO Chicago 2016Peter Lawrey
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - TalkMatthias Noback
 
The working architecture of NodeJS applications, Виктор Турский
The working architecture of NodeJS applications, Виктор ТурскийThe working architecture of NodeJS applications, Виктор Турский
The working architecture of NodeJS applications, Виктор ТурскийSigma Software
 

Similaire à Refactoring to a system of systems (20)

Secret Twists to Efficiently Develop Reactive Software Systems
Secret Twists to Efficiently Develop Reactive Software SystemsSecret Twists to Efficiently Develop Reactive Software Systems
Secret Twists to Efficiently Develop Reactive Software Systems
 
How to Overcome Data Challenges When Refactoring Monoliths to Microservices
How to Overcome Data Challenges When Refactoring Monoliths to MicroservicesHow to Overcome Data Challenges When Refactoring Monoliths to Microservices
How to Overcome Data Challenges When Refactoring Monoliths to Microservices
 
Software Architecture and Architectors: useless VS valuable
Software Architecture and Architectors: useless VS valuableSoftware Architecture and Architectors: useless VS valuable
Software Architecture and Architectors: useless VS valuable
 
L02 Architecture
L02 ArchitectureL02 Architecture
L02 Architecture
 
The Clean Architecture
The Clean ArchitectureThe Clean Architecture
The Clean Architecture
 
API-driven Legacy Migration: Results from Project Winterfell
API-driven Legacy Migration: Results from Project WinterfellAPI-driven Legacy Migration: Results from Project Winterfell
API-driven Legacy Migration: Results from Project Winterfell
 
Distributed Systems in Data Engineering
Distributed Systems in Data EngineeringDistributed Systems in Data Engineering
Distributed Systems in Data Engineering
 
Microservices architecture
Microservices architectureMicroservices architecture
Microservices architecture
 
Viktor Turskyi "Effective NodeJS Application Development"
Viktor Turskyi "Effective NodeJS Application Development"Viktor Turskyi "Effective NodeJS Application Development"
Viktor Turskyi "Effective NodeJS Application Development"
 
Infinit's Next Generation Key-value Store - Julien Quintard and Quentin Hocqu...
Infinit's Next Generation Key-value Store - Julien Quintard and Quentin Hocqu...Infinit's Next Generation Key-value Store - Julien Quintard and Quentin Hocqu...
Infinit's Next Generation Key-value Store - Julien Quintard and Quentin Hocqu...
 
netsuite-integration-whitepaper
netsuite-integration-whitepapernetsuite-integration-whitepaper
netsuite-integration-whitepaper
 
Microservices Architecture
Microservices ArchitectureMicroservices Architecture
Microservices Architecture
 
Design patterns
Design patternsDesign patterns
Design patterns
 
Microservices.pdf
Microservices.pdfMicroservices.pdf
Microservices.pdf
 
Microservices Corporate Style
Microservices Corporate StyleMicroservices Corporate Style
Microservices Corporate Style
 
Micro-services architecture
Micro-services architectureMicro-services architecture
Micro-services architecture
 
Git & dev ops come together, right now!
Git & dev ops come together, right now!Git & dev ops come together, right now!
Git & dev ops come together, right now!
 
Microservices for performance - GOTO Chicago 2016
Microservices for performance - GOTO Chicago 2016Microservices for performance - GOTO Chicago 2016
Microservices for performance - GOTO Chicago 2016
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - Talk
 
The working architecture of NodeJS applications, Виктор Турский
The working architecture of NodeJS applications, Виктор ТурскийThe working architecture of NodeJS applications, Виктор Турский
The working architecture of NodeJS applications, Виктор Турский
 

Plus de VMware Tanzu

What AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About ItWhat AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About ItVMware Tanzu
 
Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023VMware Tanzu
 
Enhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at ScaleEnhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at ScaleVMware Tanzu
 
Spring Update | July 2023
Spring Update | July 2023Spring Update | July 2023
Spring Update | July 2023VMware Tanzu
 
Platforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a ProductPlatforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a ProductVMware Tanzu
 
Building Cloud Ready Apps
Building Cloud Ready AppsBuilding Cloud Ready Apps
Building Cloud Ready AppsVMware Tanzu
 
Spring Boot 3 And Beyond
Spring Boot 3 And BeyondSpring Boot 3 And Beyond
Spring Boot 3 And BeyondVMware Tanzu
 
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdfSpring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdfVMware Tanzu
 
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023VMware Tanzu
 
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023VMware Tanzu
 
tanzu_developer_connect.pptx
tanzu_developer_connect.pptxtanzu_developer_connect.pptx
tanzu_developer_connect.pptxVMware Tanzu
 
Tanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - FrenchTanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - FrenchVMware Tanzu
 
Tanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - EnglishTanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - EnglishVMware Tanzu
 
Virtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - EnglishVirtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - EnglishVMware Tanzu
 
Tanzu Developer Connect - French
Tanzu Developer Connect - FrenchTanzu Developer Connect - French
Tanzu Developer Connect - FrenchVMware Tanzu
 
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023VMware Tanzu
 
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring BootSpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring BootVMware Tanzu
 
SpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software EngineerSpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software EngineerVMware Tanzu
 
SpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs PracticeSpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs PracticeVMware Tanzu
 
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense SolutionsSpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense SolutionsVMware Tanzu
 

Plus de VMware Tanzu (20)

What AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About ItWhat AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About It
 
Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023
 
Enhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at ScaleEnhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at Scale
 
Spring Update | July 2023
Spring Update | July 2023Spring Update | July 2023
Spring Update | July 2023
 
Platforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a ProductPlatforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a Product
 
Building Cloud Ready Apps
Building Cloud Ready AppsBuilding Cloud Ready Apps
Building Cloud Ready Apps
 
Spring Boot 3 And Beyond
Spring Boot 3 And BeyondSpring Boot 3 And Beyond
Spring Boot 3 And Beyond
 
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdfSpring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
 
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
 
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
 
tanzu_developer_connect.pptx
tanzu_developer_connect.pptxtanzu_developer_connect.pptx
tanzu_developer_connect.pptx
 
Tanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - FrenchTanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - French
 
Tanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - EnglishTanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - English
 
Virtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - EnglishVirtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - English
 
Tanzu Developer Connect - French
Tanzu Developer Connect - FrenchTanzu Developer Connect - French
Tanzu Developer Connect - French
 
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
 
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring BootSpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
 
SpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software EngineerSpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software Engineer
 
SpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs PracticeSpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs Practice
 
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense SolutionsSpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
 

Dernier

Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
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
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
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
 
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
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
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
 
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
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
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
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 

Dernier (20)

Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
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
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
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
 
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)
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
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
 
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
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
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
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 

Refactoring to a system of systems

  • 1. Refactoring to a
 System of Systems / olivergierkeOliver Gierke ƀ ogierke@pivotal.io Of monoliths, microservices and everything in between…
  • 2. 2
  • 3. 3 Monolith(aka. Big Ball of Mud) Microlith(the Careless Microservice) Modulith System
 of
 Systems 1 2 3 4 Messaging REST 6 5
  • 4. What are typical Bounded Context interactions in a monolithic application? “ 4
  • 5. What happens if these patterns are translated
 1:1 into a distributed system? “ 5
  • 6. Can we build a
 better monolith
 in the first place? “ 6
  • 7. How to translate that new approach into a distributed system? “ 7
  • 10. When a product is added to the catalog, the inventory needs to initialize its stock. “ 10
  • 11. When an order is completed, inventory shall update its stock
 for all line items. “ 11
  • 12. What do we want to focus on? • What are commonly chosen design patterns and strategies? • How do Bounded Contexts interact with each other? • What types of consistency do we deal with? • How do the systems behave in erroneous situations? • How do the different architectures support independent evolvability? 12
  • 14. A couple of warnings… The sample code is not a cookie cutter recipe of how to build things The sample code is supposed to focus on showing the interaction model between Bounded Contexts, how to model aggregates and strive for immutability as much as possible. However, to not complicate the matter, certain aspects have been kept intentionally simple to avoid further complexity to blur the focus of the samples: • Not all domain primitives are fully modeled • Monetary amounts are not modeled as such, but definitely should in real world projects. • Quantities are modeled as plain long but also should get their own value types. • Most projects use JPA for persistence. This requires us to have default constructors and some degrees of mutability in domain types. • Remote interaction is not fully implemented (not guarded against systems being unavailable etc.) 14
  • 17. The Monolith – Design Decisions + Bounded Contexts reflect into packages A (hopefully not very) typical Spring Boot based Java web application. We have packages for individual Bounded Contexts which allows us to easily monitor the dependencies to not introduce cycles. + / − Domain classes reference each other even across Bounded Contexts JPA creates incentives to use references to other domain types. This makes the code working with these types very simple at a quick glance: just call an accessor to refer to a related entity. However, this also has significant downsides: • The „domain model“ is a giant sea of entities – this usually causes problems with the persistence layer with transitive related entities as it’s easy to accidentally load huge parts of the database into memory. The code is completely missing the notion of an aggregate that defines consistency boundaries. • The scope of a transaction grows over time – Transactions can easily be defined using Spring’s @Transactional on a service. It’s also very convenient add more and more calls — and ultimately changes to entities — which blur the focus of the business transaction and making more likely to fail for unrelated reasons. 17
  • 18. The Monolith – Design Decisions + Inter-context interaction is process local As the system is running as a single process, the interaction between Bounded Contexts is performant and very simple. We don’t need any kind of object serialization and each call either succeeds or results in an exception. APIs can be refactored easily as IDEs can tweak calling and called code at the same time. − Very procedural implementation in order management The design of OrderManager.addToOrder(…) treats domain types as pure data containers. It accesses internals of Order, applies some logic to LineItems and manipulates the Order state externally. However, we can find first attempts of more domain driven methods in LineItem.increaseQuantityBy(…). 18
  • 19. The Monolith – Design Decisions − Order management actively invokes code in inventory context With the current design, services from different Bounded Contexts usually invoke each other directly. This often stems from the fact that it’s just terribly convenient to add a reference to a different managed bean via Dependency Injection and call that bean’s methods. This easily creates cyclic dependencies as the invoking code needs to know about the invoked code which in turn usually will receive types owned by the caller. E.g. OrderManagement knows about the Inventory and the Inventory accepts an Order. A side-effect of this is that the scope of the transaction all of a sudden starts to spread multiple aggregates, even across contexts. This might sound convenient in the first place but with the application growing this might cause problems as supporting functionality might start interfering with the core business logic, causing transaction rollbacks etc. 19
  • 20. The Monolith – Consequences − Service components become centers of gravity Components of the system that are hotspots in business relevance („order completed“) usually become centers of dependencies and dissolve into god classes that refer to a lot of components of other Bounded Contexts. The OrderManagement’s completeOrder(…) method is a good example for that as will have to be touched to invoke other code for every feature that’s tied to that business action. − Adding a new feature requires different parts of the system to be touched A very typical smell in that kind of design is that new features will require existing code to be touched that should not be needed. Imagine we’re supposed to introduce a rewards program that calculates bonus points for completed orders. Even if a dedicated team implements that feature in a completely separate package, the OrderManagement will eventually have to be touched to invoke the new functionality. 20
  • 21. The Monolith – Consequences + Easy to refactor The direct type dependencies allows the IDE to simplify refactorings. We just have to execute them and calling and called code gets updated. We cannot accidentally break involved third parties as there are none. Especially in scenarios where there’s little knowledge about the domain, this can be very advantageous. The interesting fact to notice here is that we have strong coupling but still can refactor and evolve relatively rapidly. This is driven by the locality of the changes. + / − Strong consistency JPA creates incentives to use references to other domain types. This usually leads to code that attempts to change the state of a lot of different entities. In conjunction with @Transactional it’s very easy to create huge chunks of changes that spread a lot of entities, which seems simple and easy in the first place. The lack of focus on aggregates leads to a lack of structure that significantly serves the erosion of architecture. 21
  • 22. The Monolith – Consequences − Order management becomes central hub for new features The lack of structure and demarcation of different parts usually manifests itself in code that implements key business cases to get bloated over time as a lot of auxiliary functionality being attached to it. In most cases it doesn’t take more than an additional dependency to be declared for injection and the container will hand it into the component. That makes up a convenient development experience but also bears the risk of overloading individual components with too many responsibilities. 22
  • 25. The Microlith – Problems + / − Simple, local transactional consistency is gone The business transaction that previously could use strong consistency is now spread across multiple systems which means we have two options: • Stick to strong consistency and use XA transactions and 2PC • „Starbucks doesn't use two-phase commit“ – Gregor Hohpe, 2004 • Switch to embracing eventual consistency and idempotent, compensating actions − Interaction patterns of the Monolith translated into a distributed system What had been a local method invocation now involves network communication, serialization etc. usually backed by very RPC-ish HTTP interaction. The newly introduced problems usually solved by adding more technology to the picture to implement well-known patterns of remote systems interaction, like bulkheads, retries, fallbacks etc. Typically found technology is Netflix Hystrix, Resilience4j, Spring Cloud modules etc. 25
  • 26. The Microlith – Problems − Remote calls executed while serving user request As this interaction pattern usually accumulates a lot of latency (especially if the called system calls other systems again) the execution module needs to switch to asynchronous executions and reactive programming, further complicating the picture. − Individual systems need to know the systems they want to invoke While the location of the system to be called can be abstracted using DNS and service discovery, systems following that architectural style tend to ignore hypermedia and hard-code resource locations to interact with into client implementations. This creates a rather strong coupling as it limits the servers ability to change it’s APIs. − Running the system requires upstream systems to be available or mocked As the invocation of other systems is a fundamental part of the execution of main business logic, these upstream systems need to be available when a system is run. This complicates testing as these systems usually need to be stubbed or mocked. 26
  • 27. The Microlith – Problems − Strong focus on API contracts As the interaction pattern between the systems is a 1:1 copy of the one practiced in the monolith, usually the same API definition techniques and practices are used. This usually oversees that this creates the same strong coupling between the communicating parties and evolvability severely suffering as the communicating parties are located at much greater distance than in the monolith. For reference, see Jim Weirich’s talk on Connascence: „As the distance between software elements increases, use weaker forms of connascence.“ Ignoring that rule produces tightly coupled distributed systems preventing independent evolution of the individual systems, a core goal of a microservice architecture in the first place. 27
  • 30. The Modulith – Fundamental differences + Focus of domain logic implementation has moved to the aggregate The aggregates become the focus point of domain logic. Key state transitions are implemented as methods on the aggregate. Some of them register even dedicated events. + Integration of Bounded Contexts is implemented using events The events produced by an aggregate are automatically published on repository interaction via Spring’s application event mechanism. This allows to define event listeners in other interested Bounded Contexts. + Invert invocation dependencies between Bounded Contexts Previously code within a Bounded Context actively reached out to other contexts and invoked operations that change state within that context. These state transitions can now be triggered by consuming events published by other Bounded Contexts. 30
  • 31. ɐ Detour: Events and Consistency 31
  • 33. Application events in a Spring application 1. We enter a transactional method Business code is executed and might trigger state changes on aggregates. 2. That transactional method produces application events In case the business code produces application events, standard events are published directly. For each transactional event listener registered a transaction synchronization is registered, so that the event will eventually be published on transaction completion (by default on transaction commit). 3. Event listeners are triggered By default, event listeners are synchronously invoked, which means they participate in the currently running transactions. This allows listeners to abort the overall transaction and ensure strong consistency. Alternatively, listeners can be executed asynchronously using @Async. They then have to take care of their transactional semantics themselves and errors will not break the original transaction. 33
  • 34. Application events in a Spring application 4. Service execution proceeds once event delivery is completed Once all standard event listeners have been invoked, the business logic is executed further. More events can be published, further state changes can be created. 5. The transaction finishes Once the transactional method is done, the transaction is completed. Usually all pending changes (created by the main business code or the synchronous event listeners) are written to the database. In case inconsistencies or connection problems, the transaction rolls back. 6. Transactional event listeners are triggered Listeners annotated with @TransactionalEventListener are triggered when the transaction commits, which means they can rely on the business operation the event has been triggered from having succeeded. This allows the listeners to read committed data. Listeners can be invoked asynchronously using @Async in case the functionality to be invoked might be long-running (e.g. sending an email). 34
  • 36. Application events with Spring (Data) • Powerful mechanism to publish events in Spring applications • Application event – either a general object or extending ApplicationEvent • ApplicationEventPublisher – injectable to manually invoke event publication • Spring Data event support • Spring Data’s focus: aggregates and repositories • Domain-Driven Design aggregates produce application events • AbstractAggregateRoot<T> – base class to easily capture events and get them published on CrudRepository.save(…) invocations. • No dependency to infrastructure APIs • Integration with messaging technology via event listeners 36
  • 37. 37 // Super class contains methods with // @DomainEvents und @AfterDomainEventPublication class Order extends AbstractAggregateRoot<Order> { Order complete() { registerEvent(OrderCompletedEvent.of(this)); return this; } }
  • 38. 38 @Component class OrderManagement { private final OrderRepository orders; @Transactional void completeOrder(Order order) { orders.save(order.complete()); } }
  • 39. Application events – Error Scenarios A synchronous event listener fails In case a normal event listener fails the entire transaction will roll back. This enables strong consistency between the event producer and the listeners registered but also bears the risk of supporting functionality interfering with the primary one, causing the latter to fail for less important reasons. The tradeoff here could be to move to a transactional event listener and embrace eventual consistency. An asynchronous event listener fails The event is lost but the primary functionality can still succeed as the event is handled in a separate thread. Retry mechanisms can (should?) be deployed in case some form of recovery is needed. 39
  • 40. Application events – Error Scenarios The transactional service execution fails Assuming the event listeners also execute transactional logic, the local transaction is rolled back and the system is still in a strongly consistent state. Transactional event listeners are not invoked in the first place. A transactional event listener fails In case a transactional event lister fails or the application crashes while transactional event listeners are executed, the event is lost and functionality might not have been invoked. 40
  • 44. Event Publication Registry 1. Write application event publication log for transactional listeners On application event publication a log entry is written for every event and transactional event listener interested in it. That way, the transaction remembers which events have to be properly handled and in case listener invocations fail or the application crashes events can be re-published. 2. Transaction listeners are decorated to register successful completion Transactional event listeners are decorated with an interceptor that marks the log entry for the listener invocation on successful listener completion. When all listeners were handled, the log only contains publication logs for the ones that failed. 3. Incomplete publications can be retried Either periodically or during application restarts. 43
  • 46. Summary Events for Bounded Context interaction Spring’s application events are a very light-weight way to implement those domain events. Spring Data helps to easily expose them from aggregate roots. The overall pattern allows loosely coupled interaction between Bounded Contexts so that the system can be extended and evolved easily. Externalize events if needed Depending on the integration mechanism that’s been selected we can now write separate components to translate those JVM internal events into the technology of choice (JMS, AMQP, Kafka) to notify third- party systems. 45
  • 47. The System of Systems 46 Ɨ ƗƗ
  • 49. What is needed for a single system to run? “ 48
  • 50. What happens if a system goes down? “ 49
  • 51. What happens if a
 failed system comes
 up again? “ 50
  • 52. What happens if a new system enters the scene? “ 51
  • 53. The System of Systems 52 Ɨ ƗƗ Messaging
  • 55. Demo • Start broker • Start individual services • Show HAL browser, APIs • Show systems interaction • Add Product -> show InventoryItem and ProductInfo being created • Trigger shipment -> show amount in InventoryItem increasing • Trigger order creation -> show amount in InventoryItem decreasing • Trigger further order creations -> show Inventory publishing OutOfStock event 54
  • 56. Key characteristics Integration via a central broker • Shared infrastructure • Some business decisions (TTL of events) in shared component • Broker knows about all messages of all systems (potentially forever) • Technology built for scale Events published as messages 55
  • 57. Key characteristics Different broker technologies have different replay characteristics • JMS — durable subscription (requires initial registration with the broker) • AMQP — fanout exchanges (requires initial registration with the broker) • Kafka — topics / partitions, log compaction Coupling via message serialization format 56
  • 58. Key characteristics Different broker technologies have different replay characteristics • JMS — durable subscription (requires initial registration with the broker) • AMQP — fanout exchanges (requires initial registration with the broker) • Kafka — topics / partitions, log compaction Coupling via message serialization format Transactional semantics • 2PC or compensating messages 56
  • 59. The System of Systems 57 Ɨ ƗƗ REST
  • 61. Event publication via HTTP resources HTTP resources for events Events are considered application state and expose HTTP resources for client consumption Typical design aspects • Collection resource filterable by: • Event type — as a replacement for topics • Publication date after — to see event • Pagination — to allow clients to define the pace at which they want to see events • Caching & conditional requests — to avoid load on the application Typical media types used • Atom feeds (XML) • HAL • Collection/JSON 59
  • 62. Event consumption via polling Clients regularly poll event resources Clients interested in events of other systems discover producing system and events resource Client under control of the consistency gap • Trade polling frequency over Typical design aspects • Low coupling through service- and resource discovery • Focus on link relations and URI templates, http://…/events{?since,type} • Polling frequency as key actuator for integration • Back-off strategies if the remote system is unavailable • Purposely bigger consistency window in case of heavy load 60
  • 63. Key characteristics + No (additional) centralized infrastructure component needed We don’t need to connect to a central, shared resource to run the system. This is eases testing. Also, HTTP interaction is usually well understood and already used in the system anyway. A lot of HTTP based technology available to help constructing the overall system (caches, proxies etc.) + Event publication is part of a local transaction Event publication does not involve interaction with an additional resource. It’s basically an additional row in the database table. + Publishing systems controls event lifecycle / security The publishing system completely controls the lifecycle of the events published. Changes in e.g. the TTL do not involve reconfiguration of infrastructure. Security implications (who is allowed to see which events?) are handled on the API level. 61
  • 64. Key characteristics + Events stay with the publishing system As events are application state, there’s no single component in the overall system that can get flooded by one system potentially flooding the overall system with events. − Bigger consistency gap because of polling The pull-model of course creates a bigger consistency gap than message listener invocation. As systems have to cope with eventual consistency anyway, this might not be a big problem. − Doesn’t scale too well for high-volume event publications In case of a lot of events per single aggregate, the aforementioned consistency gap might be unacceptable. 62
  • 65. The System of Systems 63 Ɨ ƗƗ Summary
  • 66. Key aspects • Limited remote interaction • „I like monoliths so much that I’d like to build many of them.“ — Stefan Tilkov • Separation of user requests and state synchronization • Data duplication to avoid the need to synchronously reach out to 3rd-party systems • Implicit anti-corruption layer to map models 64
  • 68. Resources Self-Contained Systems • https://scs-architecture.org Connascence • https://en.wikipedia.org/wiki/Connascence_(computer_programming) The Grand Unified Theory – Jim Weirich, 2009 • https://www.youtube.com/watch?v=NLT7Qcn_PmI Software Architecture for Developers – Simon Brown • https://leanpub.com/b/software-architecture Starbucks doesn’t use two-phase commit – Gregor Hohpe, 2004 • http://www.enterpriseintegrationpatterns.com/ramblings/18_starbucks.html 66
  • 69. Resources – Domain-Driven Design Domain-Driven Design – Eric Evans, 2003 • https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215 Implementing Domain-Driven Design – Vaughn Vernon, 2013 • https://www.amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577/ Domain-Driven Design Distilled – Vaughn Vernon, 2016 • https://www.amazon.com/Domain-Driven-Design-Distilled-Vaughn-Vernon/dp/0134434420 • https://www.amazon.de/Domain-Driven-Design-kompakt-Vaughn-Vernon/dp/3864904390 67