Skillsmatter CloudNative eXchange 2020
The microservice architecture is a key part of cloud native.
An essential principle of the microservice architecture is loose coupling.
If you ignore this principle and develop tightly coupled services the result will mostly likely be yet another "microservices failure story”.
Your application will be brittle and have all of disadvantages of both the monolithic and microservice architectures.
In this talk you will learn about the different kinds of coupling and how to design loosely coupled microservices.
I describe how to minimize design time and increase the productivity of your DevOps teams.
You will learn how how to reduce runtime coupling and improve availability.
I describe how to improve availability by minimizing the coupling caused by your infrastructure.
6. Pattern: microservice
architecture
Highly maintainable and
testable
Minimal lead time (time from
commit to deploy)
Loosely coupled
Independently deployable
Implements a business
capability
Owned/developed/tested/
deployed by a small team
An architectural
style
that structures an
application as a
set of deployable/
executable units,
a.k.a. services
A service is:
7. @crichardson
Food to Go: Microservice
architecture
Browser
Mobile
Application
API
Gateway
Order
Service
Restaurant
Service
Delivery
Service
…
Service
Order
Database
Restaurant
Database
Delivery
Database
…
Database
REST
REST
JavaScript
Message
Broker
8. @crichardson
Why microservices: success triangle
Process: Lean + DevOps/Continuous Delivery & Deployment
Organization:
Network of small,
loosely coupled, teams
Architecture:
Microservices
(sometimes)
IT must deliver software
rapidly, frequently, reliably and
sustainably
Enables:
Loose
coupling
Enables:
Testability
DeployabilityBusinesses must be
nimble, agile and
innovate faster
S/W VUCA
9. @crichardson
Loose coupling is essential
Services collaborate, e.g. Order Service must
reserve customer credit
Coupling is inevitable
BUT
Services must be loosely coupled
API
Order
Service
Customer
Service
reserveCredit()
10. Runtime coupling
Order Service cannot respond to a synchronous request (e.g.
HTTP POST) until Customer Service responds
Reduces availability
VS
Design time coupling
Change Customer Service change Order Service
Reduces development velocity
Neither is guaranteed: you must design your
services to be loosely coupled
13. Development in high performing
organizations
“Complete their work without communicating and
coordinating with people outside their team”
“Make large-scale changes to the design of their system
without depending on other teams to make changes in
their systems or creating significant work for other teams”
….
Loose design-time coupling/modularity
=
14. Need to avoid lock step
changes
Design-time coupling requires
coordination between teams:
e.g. Meetings to discuss API
changes
Slows down development
Worst case is a distributed
monolith: multiple services
frequently changing in lock step
Essential to minimize design time
coupling
API
Order
Service
Customer
Service
reserveCredit()
Change
Requires change here
Order team
Customer team
15. @crichardson
Example change: adding a
COVID delivery surcharge
interface OrderService {
Order getOrder()
…
}
class Order
…
Money tax
Money serviceFee
Money deliveryFee
…
}
No explicit
total
Money covidSurchargeNew!
Order
Service
Accounting
Service
…
Service
…
Service
Update
Calculate Calculate Calculate
Calculate
16. @crichardson
DRY (Don't repeat yourself)
services
"Every piece of
knowledge must have
a single, unambiguous,
authoritative
representation within a
system"
https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
For example:
Order Total
17. Shared library that calculates Order
Total != DRY
Shared libraries containing
business logic that changes
requires multiple services
to change/rebuild/
redeployed in lock step ❌
Shared utility libraries ✅
Service A
Library
Service B
Library
Service …
Library
Change
18. @crichardson
DRY: calculate Order Total in
the Order Service
interface OrderService {
Order getOrder()
…
}
class Order
…
Money tax
Money serviceFee
Money deliveryFee
…
}
Money total
Order
Service
Accounting
Service
…
Service
…
Service
Update
Calculate
19. @crichardson
Icebergs: expose as little as possible
Implementation
API
Small, stable
API
Large, complex
implementation
Change
What’s hidden can be
changed without
impacting client
Twilio: sendSms(from, to, message)
20. Consumer
Consume as little as possible
Postel’s Robustness
principle: https://
en.wikipedia.org/wiki/
Robustness_principle
Consumer-driven contract
tests verify compliance
Swagger/Protobuf-
generated stubs parse
everything!
{
…
"tax": …
"serviceFee": …
"deliveryFee": …
"total": "12.34"
…
}
class Order {
Money total;
}
What you ignore can’t affect you
21. The downside of sharing
database tables
Schema changes require
Coordination across teams
Overhead of maintaining
backwards compatibility
Duplication of data access logic
Updates require duplication of
consistency enforcement
business logic
Order
Service
Customer
Service
Database
Customer
table
Tight design-
time/runtime
coupling
Duplicated
code
Duplicated
code
24. @crichardson
The trouble with synchronous IPC :
runtime coupling reduced availability
Order
Service
Customer
Service
PUT /customer/id/credit
availability(createOrder) =
availability(OrderService) x
availability(CustomerService)
POST /order
😢
Order Customer
creditLimit
availableCredit
25. Problem:
Developers treat services as if they are programming
language-level modules (that communicate via HTTP)
Consequences:
IPC is relatively expensive high latency
Synchronous communication temporal coupling
reduced availability - serviceAvailabilitynumber of services
Anti-pattern: Distribution is
free
27. @crichardson
Self-contained service:
Can handle a synchronous
request without waiting for a
response from another service
https://microservices.io/patterns/decomposition/self-contained-service.html
28. @crichardson
Order
Service
Order Management
Customer Management
Improving availability: replace
service with module
POST /order
Order
Customer
creditLimit
availableCredit
availability(createOrder) =
availability(OrderService)
More available 😄
Larger service/
team 😢
Response =
validation
outcome 😄
33. @crichardson
Indirect coupling via infrastructure
Virtual infrastructure:
compute, storage, network
Kubernetes
Service Mesh
Infrastructure services:
databases, message,
brokers, …
Service
A
Service
B
Service
…
Static
Dynamic
Susceptible to
operator
misconfiguration
global impact
Services compete for
limited resources
Loosely coupled
BUT
34. The trouble with shared
infrastructure: resource contention
Order
Service
Customer
Service
Database Server
Order
Database
Customer
Database
Runaway
scenario
High resource
utilization
Unavailable
35. The trouble with shared
infrastructure: misconfiguration
Order
Service
Customer
Service
Database Server
Order
Database
Customer
Database
Unavailable
Risk of
misconfiguration
Unavailable
36. Clustering doesn’t help with
misconfiguration
Monzo bank, July 29th, 2019
Single large Cassandra
cluster that was
misconfigured
Adding capacity outage
https://monzo.com/blog/
2019/09/08/why-monzo-
wasnt-working-on-
july-29th
AWS Kinesis, Nov 25th,
2020
Attempted to expand
Kinesis “front-end fleet”
# threads (one-per-peer)
exceeded max OS limit
https://aws.amazon.com/
message/11201/
37. Database Server
Use private infrastructure: minimizes
resource contention and blast radius
Order
Service
Customer
Service
Database Server
Order
Database
Customer
Database
41. Fault isolated swim lanes
Partition/Route by
“value”, e.g.
CustomerID
And/Or
function, e.g.
User
management,
Order
Management
Virtual Infra.
Kubernetes
Service Mesh
Infra. services
Service
A
Service
B
Service
…
Routing
Async
Swim lane 1 Swim lane 2
Virtual Infra.
Kubernetes
Service Mesh
Infra. services
Service
A
Service
B
Service
…
42. @crichardson
Summary
Rapid and frequent development requires loose design-time
coupling
Loose runtime coupling is important for availability
Avoid synchronous communication but use resilience patterns
when you do
Strive for self-contained services
Avoid coupling at the infrastructure level: avoid shared
services, use swim lanes, ….