6. @jeppec
When we break up big things
into small pieces we invariably
push the complexity to their
interaction.
Michael Feathers
https://michaelfeathers.silvrback.com/microservices-until-macro-complexity
11. @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
14. @jeppec
The 11 Fallacies of Distributed Computing
These fallacies are assumptions architects, designers and developers
of distributed systems are likely to make. The fallacies will be proven
wrong in the long run - resulting in all sorts of troubles and pains for
the solution and architects who made the assumptions.
1. The network is reliable.
2. Latency is zero.
3. Bandwidth is infinite.
4. The network is secure.
5. Topology doesn't change.
6. There is one administrator.
7. Transport cost is zero.
8. The network is homogeneous.
9. The System is atomic/monolithic
10. The System is Finished
11. Business logic can and should be centralized
See https://arnon.me/wp-content/uploads/Files/fallacies.pdf
15. @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
16. @jeppec
“A distributed system is one
where a machine I’ve never
heard of can cause my
program to fail”
— Leslie Lamport
21. @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
23. @jeppec
What about cascading failures?
• In Microservice solutions that predominantly use
Request/Response style integration we often see
services calling services calling services.
• In such a setup one service aggressively retrying failed requests
can potentially bring down the other service, which in effect
can cause other services to fail, which again can cause other
services to fail.
• Performance is often also affected
• End to end latency can be several seconds
• Requires additional implementation code like:
• circuit breakers
• request/concurrency limiters
• infrastructure like a Service Mesh
25. @jeppec
Sales system
Sales
Update customer status (e.g. Gold customer)
Bookkeeping
Deliver goods
Delivery
system
Deliveries
Customer/
CRM system
Customers
SAP
Bookkeeping
Complete
Purchase
Transaction
Coordinator
Transactional
Resource
Request-to-Prepare
Commit
Prepared
Done
Prepare
Phase
Commit
Phase
2 Phase Commit
26. @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
27. @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
28. @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
30. @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/
31. @jeppec
We must split into Service
that are truly
loosely coupled
The don’t requrie Request Response style interaction between each other
and which don’t require local data duplication of other services data
(in order to avoid Request Response calls to other Services)
32. @jeppec
Services are autonomous
For a service to be autonomous is must
NOT share state
DB
Service A Service B
storeStuff(id, data)
handleStuff(id)
readStuff(id) : data
35. @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
36. @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
37. @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
39. @jeppec
Service communication
Model our data and usecases, so that all our overall
usecase can be turned into a set of independent
transactions that are asynchronously chained.
Accept
Order
?
Receive
Payment
?
Ship
Order
41. @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
42. @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
43. @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”
45. @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:
Don’t share more than
absolutely necessary.
In many cases EventType,
EntityId and a MessageId is
sufficient
46. @jeppec
This means we must switch
from a
Request/Response (pull)
to a
Reactive (push) model
A change with profound consequences
47. @jeppec
Commands & Events
• Commands mutate Aggregate state which results in one
or more Events being issued/published.
Command Event(s)
AcceptOrder OrderAccepted
ShipOrder OrderShipped
AddComment CommentAdded
QuarantineReview ReviewQuarantined
UnquarantineReview ReviewUnquarantined
48. @jeppec
Example
public class OrderService {
public void handle(AcceptOrder cmd) {
orderRepository.add(new Order(cmd.orderId,
cmd.orderLines));
eventBus.publish(new OrderAccepted(cmd.orderId,
cmd.orderLines));
}
Be aware of the Dual Write
problem.
Use the Outbox Pattern or Event
Sourcing
49. @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
MarkOrderAs
Paid
The sales
fulfillment
processing
can now
begin…
Cmd Handler
Order Paid
Apply
51. @jeppec
We need to change focus from
short technical transactions
To long running business transactions
supporting business processes
52. @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
53. @jeppec
Topic style asynchronous messaging
with a Message broker
Aka. Smart pipes and “dumb” endpoints
Service X
Publisher
Data and flow direction
Message infrastructure
(e.g. Kafka, RabbitMQ, QBus)
Service Z
Subscriber
Service Y
Subscriber
Service M
Subscriber
Topic
54. @jeppec
There are only two hard
problems in distributed
systems
2. Exactly Once Delivery
1. Guaranteed Order of Messages
2. Exactly Once Delivery
@mathiasverraes
55. @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!
56. @jeppec
Process Managers
• Process Managers are essential to the
coordination and monitoring of long running
business processes/transactions
• They work as a Finite State Machines (WorkFlow)
which handling the life cycle of Process (e.g.
Shipping an Order) and thereby forms a very
central new Aggregate in the System
• They can include manual steps/person
intervention
• Sometimes these Process Managers belong
naturally within a specific Business capability
and other times they are truly and thing by
themselves and often form new business
capabilities that way
Many companies derive their competitive advantages from their Processes.
A Process Manager allows you coordinate Business Processes on the basis of Events
58. @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
60. @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
62. @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
65. @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
67. @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)
68. @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)
69. @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
70. @jeppec
There’s cost in deploying 1000’s of microservices
(or 100.000’s serverless functions)
72. @jeppec
This means they CAN, but they don’t HAVE to be
deployed individually.
Design for Distribution
But take advantage of locality
73. @jeppec
Let’s be even more pragmatic
In which case we allow other services
to call them using local calls
74. @jeppec
Autonomous Component in code
public class PricingEngineAc extends AutonomousComponent {
public static AutonomousComponentId SERVICE_AC_ID = SALES_SERVICE_ID.ac(”pricing_engine_ac");
…
public PricingEngineAc(CurrencyConverter currencyConverter) {
this.currencyConverter = currencyConverter;
}
@Override
public void onInitialize(IConfigureACEnvironment acSetup) {
acSetup.withAutonomousComponentId(SERVICE_AC_ID)
.usingServiceDataSource()
.withBusConfiguration(cfg -> {
bus.registerReplayableTopicPublisher(InternalPricingEvents.TOPIC_NAME,
replayFromAggregate(Pricing.class)
.dispatchAggregateEventsOfType(InternalPricingEvents.class));
bus.subscribeTopic(SERVICE_AC_ID.topicSubscriber(”InventoryEvents"),
ExternalInventoryEvents.TOPIC_NAME,
new InventoryTopicSubscription(bus));
})
.runOnBusStartup((bus, axonContext) -> {
});
}
}
75. @jeppec
Autonomous Component
• Can be deployed alone or co-located, together with one or more adapters from the
same service
• Works transparently in a clustered environment
Core logic
(use case controllers/aggregates)
Primary/Driving Adapter
GUI / API / …
Primary/Driving Port
Secondary/Driven Adapter
Database/Notifications/…
Secondary/Driven Port
76. @jeppec
Alternative visualization of a Layered
architecture
Infrastructure
Data Access Logic
Business Logic
User Interface
Tests
DB File
WebService
The application is built
around data access and
other infrastructure.
Because of this coupling,
when data access, web
services, etc. change,
the business logic layer
will also have to change
77. @jeppec
Clean Architecture / Onion Architecture
Domain
Model
(Entities,
Aggregates)
Use Cases
Controllers
D
e
v
i
c
e
s
External
Interfaces
DB
File
WebService
P
r
e
s
e
n
t
e
r
s
G
ateways
W
eb
DB
U
I
Enterprise Business Rules
Application Business Rules
Interface Adapters
Frameworks & Drivers
78. @jeppec
Autonomous Components can be co-deployed
together with Application backends
web_shop (Spring Boot fat–jar)
pricing_engine_ac
discounts_ac
webshop_basket_adapters
api_products
product_details_ac
product_details_adapters
frontend
api_pricing
app
libs
products
pricing
branding
Docker is NOT a
requirement - KISS
79. @jeppec
Application in code
@Configuration
@ComponentScan(basePackages = { "com.mycoolshop.webshop",
"com.mycoolshop.adapters",
"com.mycoolshop.itops.spring" })
public class Application extends IAmASpringBootApplication {
@Override
protected ApplicationIdentifier getApplicationIdentifier() {
return ApplicationIdentifier.from(”WebShop");
}
@Override
protected Collection<AutonomousComponent> getAutonomousComponentsHostedInThisApplication() {
CurrencyExchangeRateAc currencyExchangeRateAc = new CurrencyExchangeRateAc();
return list(
new PricingEngineAc(currencyExchangeRateAc.getCurrencyConverter()),
new DiscountsAc(currencyExchangeRateAc.getCurrencyConverter()),
new InventoryAc(),
new CustomersAc(),
currencyExchangeRateAc
);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
80. @jeppec
AC, autonomy and “shared” service data
Service
DB
DB
Autonomous
Component
Autonomous
Component
Autonomous
Component
Autonomous
Component DB
81. @jeppec
50 shades of inter service AC Autonomy*
Endpoint Process Database Storage
Shared Shared Shared Shared
Own Shared Shared Shared
Own Own Shared Shared
Own Shared Own Shared
Own Own Own Shared
Own Own Own Own
Lower Autonomy
Higher Autonomy
* No RPC in use!
82. @jeppec
How do we bring things together for our users
without introducing unnecessary coupling?
86. @jeppec
iOS Home banking
Customer information
Legal and contract information
Accounts
Credit card
Mortgage loans
Web banking portal
Bank Back-office application
87. @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
88. @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
90. @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
97. @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