A common microservice architecture anti-pattern is more the merrier. It occurs when an organization team builds an excessively fine-grained architecture, e.g. one service-per-developer. In this talk, you will learn about the criteria that you should consider when deciding service granularity. I'll discuss the downsides of a fine-grained microservice architecture. You will learn how sometimes the solution to a design problem is simply a JAR file.
4. @crichardson
Agenda
How micro is a microservice?
Designing a microservice architecture
Dark matter forces: reasons to not use services
Dark energy forces: reasons to use services
7. A common conversation
Client: We are having problems testing our services. Can you
help us?
Me: Sure. How many services?
Client: 5
Me: Oh ok. BTW How many developers?
Client: 5
Me: Oh. How about merging into one service?
1 service/developer is remarkably common
8. @crichardson
Anti-pattern: The more the merrier
Excessively
fi
ne-grained
microservice architecture:
Reduced maintainability,
performance, availability, ….
https://microservices.io/post/antipatterns/2019/05/21/antipattern-more-the-
merrier.html
9. @crichardson
Agenda
How micro is a microservice?
Designing a microservice architecture
Dark matter forces: reasons to not use services
Dark energy forces: reasons to use services
10. @crichardson
How to de
fi
ne an
Architecture…
Application
≪subdomain≫
Customer
management
≪aggregate≫
Customer
≪subdomain≫
Order
management
≪aggregate≫
Order
createCustomer()
createOrder()
fi
ndOrder()
fi
ndOrderHistory()
System operations
Distill
Requirements The “requests” that the
application implements
Have SLOs
Customer Team
Order Team
About Subdomains
• Business capability/function/etc
• Logical view: packages and classes
• Team-sized
• Loosely coupled (Conways law)
1
2
Functional requirements
As a consumer
I want to place an Order
So that I can ….
As a Restaurant
I want to accept an Order
So that I can ….
Event storming
Wireframe/UI mockups
Available
Restaurants
Restaurant
Menu
System quality attributes
• SLA: Reliability/Latency
• Scalability
• …
12. @crichardson
Kitchen Service
Delivery Service
Order Service
createOrder()
… how to de
fi
ne an Architecture
createOrder()
<<subdomain>>
Order Management
Order
System operations
<<subdomain>>
Order
Management
<<subdomain>>
Kitchen
Management
<<subdomain>>
Delivery
Management
<<subdomain>>
Courier
Management
Group
subdomains
into services
Application
Collaboration
Design
collaborations
for distributed
operations
createOrder()
3
13. @crichardson
Grouping subdomains into
components: together or separate?
≪subdomain≫
Customer Mgmt.
≪aggregate≫
Customer
≪subdomain≫
Order Mgmt.
≪aggregate≫
Order
Attraction
Repulsion
Simple components
Team-sized services
Fast deployment pipeline
…
Dark energy: an anti-
gravity that’s accelerating
the expansion of the
universe
Dark matter: an invisible
matter that has a
gravitational effect on stars
and galaxies.
https://www.nasa.gov/feature/goddard/2020/new-hubble-data-explains-missing-dark-matter
Simple, ef
fi
cient interactions
Prefer ACID over BASE
Minimize runtime coupling
…
https://chrisrichardson.net/post/microservices/2021/04/15/mucon-2021-dark-energy-dark-matter.html
Generate
systemOperation()
14. @crichardson
Dark energy and dark matter
forces
Subdomain A
«Aggregate»
X
Subdomain B
«Aggregate»
Y
Service A Service B
Attraction
Simple interactions
Efficient interactions
Prefer ACID over BASE
Minimize runtime coupling
Minimize design time coupling
Simple components
Team autonomy
Fast deployment pipeline
Support multiple technology stacks
Segregate by characteristics
Repulsion
Dark energy
Dark matter
Metaphor for
Metaphor for
15. @crichardson
Let’s imagine you are
implementing Coupons…
Order
Service
<<subdomain>>
Order
Management
Customer
Service
<<subdomain>>
Customer
Management
createCustomer() createOrder()
<<subdomain>>
Coupon
Management
createCoupon(discount, …)
+ couponID
redeem(couponID)
Which service?
reserve
Credit()
16. @crichardson
Order
Service
Key decision: New service or
existing service?
Coupon
Service
Order
Service
<<subdomain>>
Order
Management
<<subdomain>>
Coupon
Management
Customer
Service
<<subdomain>>
Customer
Management
<<subdomain>>
Order
Management
<<subdomain>>
Coupon
Management
Customer
Service
<<subdomain>>
Customer
Management
OR
Note: Customer+Coupon Service is another option
17. @crichardson
Agenda
How micro is a microservice?
Designing a microservice architecture
Dark matter forces: reasons to not use services
Dark energy forces: reasons to use services
18. @crichardson
Dark matter attractive forces
subdomains in same service
https://chrisrichardson.net/post/microservices/2021/04/15/mucon-2021-dark-energy-dark-matter.html
Subdomain A
«Aggregate»
X
Subdomain B
«Aggregate»
Y
Service A Service B
Simple interactions
Efficient interactions
Prefer ACID over BASE
Minimize runtime coupling
Minimize design time coupling
Generates
SystemOperation()
Collaboration
19. @crichardson
Dark matter forces: reasons to colocate
Order and Coupon management
Coupon
Service
Order
Service
Order Service
<<subdomain>>
Order
Management
<<subdomain>>
Order
Management
<<subdomain>>
Coupon
Management
<<subdomain>>
Coupon
Management
But do they apply in this situation?
Does de
fi
ning a new service create a problem?
21. @crichardson
Question: is each distributed
operation simple?
Additional
interaction
Additional
participant
Minimal increase in complexity but eventually …
22. @crichardson
Distributed invocations are
expensive
Local method call: customerService.reserveCredit(customerID, amount)
Testing with mock objects
vs.
Distributed invocation:
CustomerServiceProxy
CustomerController
Sagas, compensating transactions, partial failure
Consumer-driven contract tests
…
24. @crichardson
Question: is each distributed
operation ef
fi
cient enough?
Additional sequential interaction
Minimal reduction in ef
fi
ciency but eventually …
25. @crichardson
Prefer ACID over BASE
System
Operation()
Service
Subdomain
A
Subdomain
B
Service B
Service A
Subdomain
A
Subdomain
B
System
Operation()
Distributed, eventually
consistent transaction Simple, Local ACID transaction
vs.
ACID txn ACID txn
ACID txn
26. @crichardson
Question: is the distributed
operation “suf
fi
ciently” ACID?
Step Participant Transaction
Compensating
Transaction
1 Order Service createOrder() rejectOrder()
2 Coupon Service redeemCoupon() unredeemCoupon()
3 Customer Service reserveCredit() -
4 Order Service approveOrder() -
Create Order Saga
Doable but much more complex…
28. @crichardson
Question: does the distributed operation
meet its latency/availability SLO?
All must be available
More available
More complex
Wait
No Wait
29. @crichardson
Risk: Silo’d teams have dif
fi
culty
identifying excessive runtime coupling
Payment Team:
“We just call the Fraud Service”
Fraud Team: “We have lots of services”
30. @crichardson
Minimize design time coupling
Order
Subdomain
Customer
Subdomain
reserveCredit()
createOrder()
Customer
Order
Design-time coupling
Minimize with careful design
BUT
You can’t always eliminate it
Risk of lock step changes
API
Risk proportional to:
• API instability
• API complexity
• …
31. @crichardson
Question: are the two subdomains
suf
fi
ciently design-time decoupled?
interface CouponManagement {
redeemCoupon(couponID, amount)
interface CouponManagement {
redeemCoupon(couponID, amount, orderLineItems)
Not bad ✅
More complex, coupled to order concept ❌
vs.
32. @crichardson
Agenda
How micro is a microservice?
Designing a microservice architecture
Dark matter forces: reasons to not use services
Dark energy forces: reasons to use services
33. @crichardson
Dark energy repulsive forces
subdomains in different services
https://chrisrichardson.net/post/microservices/2021/04/15/mucon-2021-dark-energy-dark-matter.html
Service
Service
«Subdomain» A
«Aggregate»
X
«Subdomain» B
«Aggregate»
Y
Simple components
Team autonomy
Fast deployment pipeline
Support multiple technology stacks
Segregate by characteristics
Repulsive dark energy forces
34. @crichardson
Dark energy forces: reasons
to create a Coupon Service
Coupon
Service
Order
Service
Order Service
<<subdomain>>
Order
Management
<<subdomain>>
Order
Management
<<subdomain>>
Coupon
Management
<<subdomain>>
Coupon
Management
But do they apply in this situation?
Does de
fi
ning a new service solve a problem?
36. Question: is the Order+Coupon
Service excessively complex?
Coupon management:
reasonably simple, no new
dependencies, …
Minimal additional complexity
Therefore
Separate Coupon Service is not
required
But
If Coupon management
becomes complex then separate
Order Service
main
main
Order Management
orders.web
couponAPI
orders.
domain
Coupon Management
coupons.
persistence
orders.
persistence
Coupon team
Order team
coupons.
domain
coupons.web
coupons.api
Modular Order Service
37. @crichardson
Team autonomy = service per team
Service
Service
Service
Subdomain
A
Subdomain
A
Subdomain
B
Subdomain
B
Coordination required
Contention for resources
Develop, push, build, test
and deploy independently
vs.
Team A Team B Team A Team B
38. @crichardson
Question: impact of a single Order
Service on team autonomy?
Who develops Coupon Management?
Orders team
Team autonomy is not an issue
Embed Coupon Management in Order Service
Different team, e.g. Coupons Team:
How much autonomy would they lose?
A few teams = probably ok
But there’s a limit
40. Question: Impact of adding Customer
Management to the Order Service?
Increase on test execution time?
testExecutionTime(Coupon
Management)?
Incremental build and test? Worst
case: changing one subdomain
requires testing the other
Increase in commit frequency?
More developers = more commits
Possibility of delays due to queuing
Order Service
main
main
Order Management
orders.web
couponAPI
orders.
domain
Coupon Management
coupons.
persistence
orders.
persistence
coupons.
domain
coupons.web
coupons.api Stable?
42. @crichardson
Question: does Coupon Management
introduce technology stack issues?
Does Coupon Management use the same technology stack as
Order Management?
Same language, framework
Compatible transitive dependencies
Does Coupon Management introduce new dependencies that
would complicate technology upgrades?
Service upgrade effort proportional # dependencies
A dependency might not support newer versions of libraries,
JDK, etc
43. @crichardson
Separate subdomains by
characteristics
Subdomain characteristic Issue
Resource requirements Cost-effective, scalability
Regulations, e.g. SaMD/
PCI
DevOps vs. Slower regulated process
Business criticality/tier Maximize availability
Security, e.g. PII, … Improve security
DDD core/supporting/
generic
Focus on being competitive
45. @crichardson
Example: Segregate by business criticality
Service
Service
Service
Payment
Processing
Payment
Processing
Merchant
management
Merchant
management
Shared infrastructure
Shared code base
Risk of interference
Separate infrastructure
Separate code base
Isolated
vs.
chargeCard()
2.9% + 30c/
request Revenue loss and penalties
chargeCard()
Critical
Important
46. @crichardson
Question: How does Coupon
Management compare to Order
Service?
Subdomain characteristic Same?
Resource requirements ✅
Regulations, e.g. SaMD/
PCI
✅
Business criticality/tier ✅
Security, e.g. PII, … ✅
DDD core/supporting/
generic
✅
47. @crichardson
Summary: designing Coupon Management
Part of Order Service Coupon Service
Dark energy, repulsive forces
Simple components
✅
Doesn’t solve a
problem
Team autonomy
Fast deployment pipeline
Support multiple technology stacks
Segregate by characteristics
Dark matter, attractive forces
Simple interactions
✅
✅❌
Ef
fi
cient interactions ✅
Prefer ACID over BASE ❌
Minimize runtime coupling ❌✅
Minimize design-time coupling ✅
Creates
problems
48. @crichardson
Summary
Don’t take MICROservices literally
Designing a microservice architecture
Dark energy forces = reasons to use services
Dark matter forces = reasons to not use services
Con
fl
icting forces => must make trade-offs
Implementing subdomains:
JARs by default
As a service to solve a tangible dark energy-related problem
https://www.nasa.gov/feature/goddard/2019/nasa-s-james-webb-space-telescope-has-been-assembled-for-the-
fi
rst-time