Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Alternative Microservices
One size doesn’t fit all
Jeppe Cramon - @jeppec
Cloud Create ApS
@jeppec
Alternative facts?
• Splitting a monolith into microservices is easy
• By making things small we automatically red...
@jeppec
Splitting a monolith into microservices is easy
Component A
Component B
doStuff(data)
Component A
Component B
doSt...
@jeppec
DB
Splitting a monolith into microservices is easy
Component A Component B
storeStuff(id, data)
handleStuff(id)
re...
@jeppec
Alternative facts?
• Splitting a monolith into microservices is easy
• By making things small we automatically red...
@jeppec
Is Monolith vs Microservice the whole story?
VS
MonolithMicroservices
@jeppec
Is Monolith vs Microservice the whole story?
MonolithMicroservicesServerless Functions
Deployment Unit Granularity
@jeppec
When we break up big things
into small pieces we invariably
push the complexity to their
interaction.
Michael Feat...
@jeppec
@jeppec
Microservices turns a
local function call
into a distributed problem
Avoid remote calls!
@jeppec
With cross SERVICE integration we’re bound
by the laws of distributed computing
@jeppec
The 8 Fallacies of Distributed Computing
These fallacies are assumptions architects, designers and developers of
d...
@jeppec
Essential complexity of 2 way integration
Component CComponent BComponent A
UI
Service Service
B:Service()
call C...
@jeppec
B:Service()
call C:Service()
call A:Service()
if (A:Call-Failed:Too-Busy?)
Wait-A-While()
call A:Service()
if (A:...
@jeppec
Service autonomy
Component
B
Component
C
Component
A
System X
Service A
Component
B
Component
C
System X
Slow/unre...
@jeppec
Then why ever split up into smaller parts?
@jeppec
Crippling coupling
Death by a 1000 cuts
@jeppec
Reality rears its ugly head
@jeppec
One of the signs are rigidity
Changing one thing requires you to modify a lot of other code
to make the codebase c...
@jeppec 20
When you change a thing you end up
breaking something else!
@jeppec
“Nobody is allowed to modify that module!”
or
“Let’s rewrite!”
21
@jeppec
CORE problem?
@jeppec
High coupling
@jeppec
Monoliths can be well designed
Unfortunately many monoliths experience high degrees of coupling, resulting in them...
@jeppec
This highly depends on
• How likely are things to change
• And what parts that change together
25
@jeppec 26
@jeppec 27
@jeppec
Result is often fragmented domain logic
Focus on Nouns (Entities)
and retrofit Verbs later
28
@jeppec 29
Customer
CustomerId
FirstName
LastName
Email
…
Order
OrderId
Total
DeliveryAddress
Status
…
OrderLine
Quantity
...
@jeppec
If we primarily model around nouns/entities we can
easily violate the SRP
Where a change to requirements
is likely...
@jeppec
Business introduces new rule
Product price depends on Customer Status
@jeppec 32
Customer
CustomerId
FirstName
LastName
Email
Status
…
Order
OrderId
Total
DeliveryAddress
Status
…
OrderLine
Qu...
@jeppec
Jim Coplien
33
@jeppec
instead of focusing on Nouns!
34
@jeppec
When discussing use cases with Business Experts
35
@jeppec
and what fields that are separate
36
@jeppec 37
@jeppec 38
Customer
CustomerId
FirstName
LastName
Email
Status
…
Product
ProductId
Name
Description
Images
Price
Decomposi...
@jeppec
But don’t name the piles before you know what they are
This avoids cognitive bias!
39
@jeppec
Give the piles made up names, such as colors
40
@jeppec
@jeppec
Shopping for computer parts
Product search & details
@jeppec
Product
Image
(small)
SKU
(Stock
Keeping Unit)
Tag(s)
Product
name
Delivery
estimate
Normal
price
Discounted
price...
@jeppec
Product
Image
(large)
SKU
(Stock
Keeping Unit)
Tag(s)
Product
name
Delivery
estimate• Producer
• SKU
• Model no
• ...
@jeppec
When linking data
Focus on identity instead of entity
@jeppec
Linked to Product Id:
• Product image (small)
• Product image (large)
• Additional product images
Product
Image
(l...
@jeppec
View Shopping basket
@jeppec
Product
Image
(small)
SKU
(Stock
Keeping Unit)
Product
name
Delivery
estimate
Item Price
promised
Stock
status
Rem...
@jeppec
Product
Image
(small)
SKU
(Stock
Keeping
Unit)
Product
name
Delivery
estimate
Item Price
promised
Stock
status
Rem...
@jeppec
Check out process
@jeppec
Order Id
• Customer/customer-id
@jeppec
Order Id
• Customer/customer-id
Linked to Order Id:
• Order Delivery address
• Order Shipping method
• Product pri...
@jeppec
• Payment Type
Linked to Order Id:
• Order Payment information
• Payment Type Fee
• Product price
• Product discou...
@jeppec
What are the these problem domain piles?
54
@jeppec 55
@jeppec
If we align the problem domain with the solution domain
Bounded Context 1 Bounded Context 3Bounded Context 2
UI
BL...
@jeppec
Which is very different from
“The” DB
UI
Logic
Data Access
@jeppec
What are the solution domain piles?
58
@jeppec
A Service is
• The technical authority for a given bounded context
• It is the owner of all the data and business ...
@jeppec 60
@jeppec
Microservices promise a solution
to our problem
Monolith
Microservice Microservice
Microservice MicroserviceMicros...
@jeppec
There’s never time to do it right
But there’s always time to do it over
62
@jeppec 63
@jeppec
DB
Remember?
Component A Component B
storeStuff(id, data)
handleStuff(id)
readStuff(id) : data
@jeppec
If we want a scalable and loosely coupled design
We could seek inspiration from…
65
@jeppec
Life Beyond Distributed Transactions
by Pat Helland
1. How do we split our data
2. How do we identify our data
3. ...
@jeppec
1. How do we split our data
Data must be collected in pieces called aggregates. These aggregates
should be limited...
@jeppec
Domain Driven Design
The term Aggregate comes from DDD
@jeppec
Aggregates
Invoice
InvoiceLine
*
Account *
What:
• Cluster coherent Entities and Value Objects, with
complex assoc...
@jeppec
2. How do we identify our data
According to Pat Helland we need to be able to uniquely identify each
Aggregate usi...
@jeppec
Aggregates refer to each other by ID
they NEVER use memory pointers, join tables or remote calls
@jeppec
Services/Bounded Contexts and Aggregates
Sales
Product
Customer
customerId
…
Order
orderId
customerId
…
OrderLine
...
@jeppec
3. How do we communicate between our services
What do we do when our use case involves more than
one aggregate and...
@jeppec
Synchronous calls are the crystal meth of programming
At first you make good progress but then the sheer horror
be...
@jeppec
What’s the challenge with
using RPC/REST/SOAP/…
between services?
@jeppec
Synchronous calls lower our tolerance for faults
• When you get an IO error
• When servers crash or restarts
• Whe...
@jeppec
Also remember: REST isn’t magic!
@jeppec
Services are autonomous
For a service to be autonomous is must
NOT share state
DB
Service A Service B
storeStuff(i...
@jeppec
Services are autonomous
Autonomy is essential for
Scalability (scale out clustering)
Reliability (fail over cluste...
@jeppec
Services are autonomous
Autonomy is essential for
Reusability
Adaptability
@jeppec
Coupling matrix*
* Modified version of Ian Robinson’s matrix: http://iansrobinson.com/2009/04/27/temporal-and-beha...
@jeppec
We need to change focus from short
technical transactions
To long running business transactions supporting
busines...
@jeppec
Using Business Events to drive Business Processes
Sales Service
Shipping
Billing
Sales
Customers
MessageChannel
On...
@jeppec
Events
An Event is non-prescriptive of what should happen in other parts of the
system. It leaves this open to the...
@jeppec
Choreographed Event Driven Processes
Sales Service
Order
Accepted
Billing Service
Order Fulfilment
(Saga/
Process-...
@jeppec
Service and deployment
• A Service represents a logical responsibility boundary
• Logical responsibility and physi...
@jeppec
@jeppec
Service Microservices
1..*
Is implemented by
A Service is the technical authority of a specific
Bounded-Context/Bu...
@jeppec
Service Microservices
1..*
Is implemented by
Service vs Microservices
Microservices are a division of Services alo...
@jeppec
A Service represents a logical boundary
90
Service
Microservice
Microservice Microservice
Microservice
@jeppec
Services are the corner stone
• We talk in terms of Services capabilities and the processes/use-cases
they support...
@jeppec
Microservices is an architectural style
92
@jeppec
Service deployment
• Many services can be deployed to the same physical server
• Many services can be deployed in ...
@jeppec
There’s cost in deploying 1000’s of microservices
(or 100.000’s serverless functions)
94
@jeppec
Autonomous Components
Not everything needs to be individually deployable
95
@jeppec
This means they CAN, but they don’t HAVE to be deployed
individually.
Design for Distribution
But take advantage o...
@jeppec
Let’s be even more pragmatic
In which case we allow other services
to call them using local calls
97
@jeppec
AC in code
public class PricingEngineAc extends AutonomousComponent {
public static AutonomousComponentId SERVICE_...
@jeppec
Autonomous Component
• Can be deployed alone or co-located, together with one or more adapters from the same servi...
@jeppec
Autonomous Components can be co-deployed together
with Application backends
web_shop (Spring Boot fat–jar)
pricing...
@jeppec
AC, autonomy and “shared” service data
Service
DB
DB
Autonomous
Component
Autonomous
Component
Autonomous
Componen...
@jeppec
50 shades of inter service AC Autonomy*
Endpoint Process Database Storage
Shared Shared Shared Shared
Own Shared S...
@jeppec
How do we bring things together for our users
without introducing unnecessary coupling?
103
@jeppec
Let’s look at Applications
@jeppec
iOS Home Banking
Customer information
Legal and contract information
Accounts
@jeppec
iOS Home banking
Customer information
Legal and contract information
Accounts
Credit card
Mortgage loans
Web banki...
@jeppec
Let’s assume we have these services
Currency
Service
Customer
Service
Identity
Management
Service
Sales
Service
In...
@jeppec
Back-end for Front-end?
Client
Remote Facade
DTOs
Identity
Management
Service
Customer
Service
Products
Service
Sa...
@jeppec
Service A Service B Service C
IT-OPS
Web shop
Warehouse
Back office
App logic
(Layered, CQRS,…)
Warehouse
Storage
...
@jeppec 110
@jeppec 111
@jeppec
Composite page example
Page Context:
{id: ISBN-10 0-321-83457-7 }
Images
Books
Reviews
Pricing
Inventory
OthersAls...
@jeppec
A Service represents a logical boundary
113
Service
Autonomous
Component
Autonomous
Component
Adapter
UI component
@jeppec
An Application is the plate where Components are
co-deployed
114
Sales service components
Inventory service compon...
@jeppec
An UI is composed of
widgets from
different services
115
@jeppec
Widget Widget
Page
Widget
Widget
Widget Widget
• Overall structure of the page
is “owned” by the application.
• Ea...
@jeppec 117
@jeppec
Page Rendering Example
Page Ctrl
Sales
Service
UI Broker
Customer
Service
Pricing
Service
Product
Service
Page
Wid...
@jeppec
Application in code
@Configuration
@ComponentScan(basePackages = { "com.mycoolshop.webshop",
"com.mycoolshop.adapt...
@jeppec
How do you search across services?
Product
Feature
Product
Price
Producer
Product
Price
@jeppec
Matching
Product Id’s
SearchEngine
IFilterProducts<ProductId>
How do you search across services?
Product
Feature
P...
@jeppec 122
@jeppec
Distributed
Bus
Topics
Queues
Distributed per Service
EventBus
Distributed
Notifications
Distributed
Broadcast
Dis...
@jeppec
pricing_engine_ac
(deployed on 10.25.26.102)
pricing_engine_ac
(deployed on 10.25.26.101)
Bus Bus
Bus Bus
inventor...
@jeppec
CreateOrder
Sales Service : Orders_Ac
Webshop Application
Customer Service : Customer_Agreements_Ac
OrderCreated
O...
@jeppec
Client handled subscriptions
• Highly resilient pattern for an Event Driven Architecture that’s backed by
Event-So...
@jeppec
Client handled subscriptions
Publisher
Subscriber A
Local storage
EventStore
Subscriber B
Local storage
Topic
Subs...
@jeppec
5 Microservices Do’s
• Identify Bounded Contexts (or Business Capabilities) and split your services according to t...
@jeppec
5 Microservices Don’ts
• Do not introduce a network boundary as an excuse to write better code - many have trouble...
Thanks :)
Blog: https://cramonblog.wordpress.com/
Homepage: http://cloudcreate.dk/
Twitter: @jeppec
Upcoming SlideShare
Loading in …5
×

Alternative microservices - one size doesn't fit all

506 views

Published on

A different look at microservices. Is there only one way to approach microservices, what are the pit falls, what protocols and communication patterns should we use. How do we discover service boundaries? What role does applications and the UI play?

Published in: Technology
  • Be the first to comment

Alternative microservices - one size doesn't fit all

  1. 1. Alternative Microservices One size doesn’t fit all Jeppe Cramon - @jeppec Cloud Create ApS
  2. 2. @jeppec Alternative facts? • Splitting a monolith into microservices is easy • By making things small we automatically reduce coupling
  3. 3. @jeppec Splitting a monolith into microservices is easy Component A Component B doStuff(data) Component A Component B doStuff(data)
  4. 4. @jeppec DB Splitting a monolith into microservices is easy Component A Component B storeStuff(id, data) handleStuff(id) readStuff(id) : data
  5. 5. @jeppec Alternative facts? • Splitting a monolith into microservices is easy • By making things small we automatically reduce coupling • By providing enough unit testing we can ensure that our services work together • Microservices will automatically make you scale • Monitoring is simple • Deployment overhead is low • Refactoring is easy (write and throw away)
  6. 6. @jeppec Is Monolith vs Microservice the whole story? VS MonolithMicroservices
  7. 7. @jeppec Is Monolith vs Microservice the whole story? MonolithMicroservicesServerless Functions Deployment Unit Granularity
  8. 8. @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
  9. 9. @jeppec
  10. 10. @jeppec Microservices turns a local function call into a distributed problem Avoid remote calls!
  11. 11. @jeppec With cross SERVICE integration we’re bound by the laws of distributed computing
  12. 12. @jeppec The 8 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. See http://www.rgoarchitects.com/Files/fallacies.pdf for a walkthrough of the fallacies and why they’re fallacies
  13. 13. @jeppec Essential complexity of 2 way integration Component CComponent BComponent A UI Service Service B:Service() call C:Service() call A:Service() commit() Service Local transaction between Component A, B and C
  14. 14. @jeppec B:Service() call C:Service() call A:Service() if (A:Call-Failed:Too-Busy?) Wait-A-While() call A:Service() if (A:Call-Failed:Too-Busy?) Wait-A-Little-While-Longer() call A:Service() if (A:Call-Failed:IO-Error?) Save-We-Need-Check-If-Call-A-Succeded-After-All AND We-Need-To-Retry call C:Service and call B:Service AND Tell-Customer-That-This-Operation-Perhaps-Went-Well if (A:Call-Went-Well?) commit() Accidental complexity from distributed service integration Component CComponent BSystem A UI Service Service Service Local transaction between Component B and C
  15. 15. @jeppec Service autonomy Component B Component C Component A System X Service A Component B Component C System X Slow/unreliable network Different SLA Slow system
  16. 16. @jeppec Then why ever split up into smaller parts?
  17. 17. @jeppec Crippling coupling Death by a 1000 cuts
  18. 18. @jeppec Reality rears its ugly head
  19. 19. @jeppec One of the signs are rigidity Changing one thing requires you to modify a lot of other code to make the codebase consistent again 19
  20. 20. @jeppec 20 When you change a thing you end up breaking something else!
  21. 21. @jeppec “Nobody is allowed to modify that module!” or “Let’s rewrite!” 21
  22. 22. @jeppec CORE problem?
  23. 23. @jeppec High coupling
  24. 24. @jeppec Monoliths can be well designed Unfortunately many monoliths experience high degrees of coupling, resulting in them earning a bad name
  25. 25. @jeppec This highly depends on • How likely are things to change • And what parts that change together 25
  26. 26. @jeppec 26
  27. 27. @jeppec 27
  28. 28. @jeppec Result is often fragmented domain logic Focus on Nouns (Entities) and retrofit Verbs later 28
  29. 29. @jeppec 29 Customer CustomerId FirstName LastName Email … Order OrderId Total DeliveryAddress Status … OrderLine Quantity Product ProductId Name Images Price Others have bought
  30. 30. @jeppec If we primarily model around nouns/entities we can easily violate the SRP Where a change to requirements is likely to require changes to multiple entity classes 30
  31. 31. @jeppec Business introduces new rule Product price depends on Customer Status
  32. 32. @jeppec 32 Customer CustomerId FirstName LastName Email Status … Order OrderId Total DeliveryAddress Status … OrderLine Quantity Product ProductId Name Description Images Price Others have bought What now?
  33. 33. @jeppec Jim Coplien 33
  34. 34. @jeppec instead of focusing on Nouns! 34
  35. 35. @jeppec When discussing use cases with Business Experts 35
  36. 36. @jeppec and what fields that are separate 36
  37. 37. @jeppec 37
  38. 38. @jeppec 38 Customer CustomerId FirstName LastName Email Status … Product ProductId Name Description Images Price Decomposing the domain Customer FirstName LastName Customer Status Product Price Product Name Description
  39. 39. @jeppec But don’t name the piles before you know what they are This avoids cognitive bias! 39
  40. 40. @jeppec Give the piles made up names, such as colors 40
  41. 41. @jeppec
  42. 42. @jeppec Shopping for computer parts Product search & details
  43. 43. @jeppec Product Image (small) SKU (Stock Keeping Unit) Tag(s) Product name Delivery estimate Normal price Discounted price (this weekend) Product description (short) Stock status
  44. 44. @jeppec Product Image (large) SKU (Stock Keeping Unit) Tag(s) Product name Delivery estimate• Producer • SKU • Model no • EAN • Link to producer Discount limitations (time frame, number of items) Product description (full) Stock status Discounted price (this weekend) Normal Price Stock status (detailed)
  45. 45. @jeppec When linking data Focus on identity instead of entity
  46. 46. @jeppec Linked to Product Id: • Product image (small) • Product image (large) • Additional product images Product Image (large) Product Id: • Product tag • Product name • Product producer-id • Product description (short) • Product description (full) • Model no • EAN Tag(s) Product name • SKU • Model no • EAN Product description (full) Linked to Product Id: • Product price • Product discount Discount limitations (time frame, number of items) Discounted price (this weekend) Normal Price Linked to Product Id: • SKU • Stock status • Product delivery information SKU (Stock Keeping Unit) Delivery estimate Stock status Stock status (detailed) Linked to Producer Id: • Producer name • Link to producer
  47. 47. @jeppec View Shopping basket
  48. 48. @jeppec Product Image (small) SKU (Stock Keeping Unit) Product name Delivery estimate Item Price promised Stock status Remaining product reservation time Combined Delivery estimate Payment Type Fee Quantity Total price Sub total
  49. 49. @jeppec Product Image (small) SKU (Stock Keeping Unit) Product name Delivery estimate Item Price promised Stock status Remaining product reservation time Combined Delivery estimate Payment Type Fee Quantity Total price Sub total Linked to Product Id: • Product price • Product discount Linked to Order Id: • Order item quantity • Order item subtotal • Order shipping price • Order Payment Fee • Order total • Order reservation time
  50. 50. @jeppec Check out process
  51. 51. @jeppec Order Id • Customer/customer-id
  52. 52. @jeppec Order Id • Customer/customer-id Linked to Order Id: • Order Delivery address • Order Shipping method • Product price • Product discount Linked to Order Id: • Order item quantity • Order item subtotal • Order shipping price • Order total
  53. 53. @jeppec • Payment Type Linked to Order Id: • Order Payment information • Payment Type Fee • Product price • Product discount Linked to Order Id: • Order item quantity • Order item subtotal • Order shipping price • Order Payment Fee • Order total
  54. 54. @jeppec What are the these problem domain piles? 54
  55. 55. @jeppec 55
  56. 56. @jeppec If we align the problem domain with the solution domain Bounded Context 1 Bounded Context 3Bounded Context 2 UI BL DAO UI BL DAO UI BL DAO Vertical coupling is unavoidable We want to avoid horizontal coupling
  57. 57. @jeppec Which is very different from “The” DB UI Logic Data Access
  58. 58. @jeppec What are the solution domain piles? 58
  59. 59. @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/
  60. 60. @jeppec 60
  61. 61. @jeppec Microservices promise a solution to our problem Monolith Microservice Microservice Microservice MicroserviceMicroservice Microservice Microservice
  62. 62. @jeppec There’s never time to do it right But there’s always time to do it over 62
  63. 63. @jeppec 63
  64. 64. @jeppec DB Remember? Component A Component B storeStuff(id, data) handleStuff(id) readStuff(id) : data
  65. 65. @jeppec If we want a scalable and loosely coupled design We could seek inspiration from… 65
  66. 66. @jeppec Life Beyond Distributed Transactions by Pat Helland 1. How do we split our data 2. How do we identify our data 3. How do we communicate between our services
  67. 67. @jeppec 1. How do we split our data Data must be collected in pieces called aggregates. These aggregates should be limited in size (but not smaller), so that, after a transaction they are consistent. Rule of thumb: One transaction involves only one aggregate.
  68. 68. @jeppec Domain Driven Design The term Aggregate comes from DDD
  69. 69. @jeppec Aggregates Invoice InvoiceLine * Account * What: • Cluster coherent Entities and Value Objects, with complex associations into Aggregates with well defined boundaries. • Choose one entity to be root and control access to objects inside the boundary through the root. Motivation: Control invariants and consistency through the aggregate root. Ensuring consistency & transactional boundaries for Distributed scenarios! Root * *
  70. 70. @jeppec 2. How do we identify our data According to Pat Helland we need to be able to uniquely identify each Aggregate using an ID. • This ID will usually a UUID/GUID {21EC2020-3AEA-4069-A2DD-08002B30309D} 2122 (approximately 5.3×1036) combinations
  71. 71. @jeppec Aggregates refer to each other by ID they NEVER use memory pointers, join tables or remote calls
  72. 72. @jeppec Services/Bounded Contexts and Aggregates Sales Product Customer customerId … Order orderId customerId … OrderLine orderId productId quantity timestamp … ProductCategory productCategoryId … Pricing Product productId productCategoryId name tag ... Product-Price productId normalPrice discountPeriods …
  73. 73. @jeppec 3. How do we communicate between our services What do we do when our use case involves more than one aggregate and therefore likely more than one service?
  74. 74. @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
  75. 75. @jeppec What’s the challenge with using RPC/REST/SOAP/… between services?
  76. 76. @jeppec Synchronous calls lower 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 style Service interaction we can loose business data if there’s no automatic retry Or we risk creating data more than once if the operation isn’t idempotent* Client Server Duplicated Response Duplicated Request Processing Response Request 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
  77. 77. @jeppec Also remember: REST isn’t magic!
  78. 78. @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
  79. 79. @jeppec Services are autonomous Autonomy is essential for Scalability (scale out clustering) Reliability (fail over clustering)
  80. 80. @jeppec Services are autonomous Autonomy is essential for Reusability Adaptability
  81. 81. @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 Event oriented Command oriented Emergency services Distributed 3 layer
  82. 82. @jeppec We need to change focus from short technical transactions To long running business transactions supporting business processes
  83. 83. @jeppec Using Business Events to drive Business Processes Sales Service Shipping Billing Sales Customers MessageChannel Online Ordering System Web Shop (Composite UI) Billing Service Shipping Service Order Accepted AcceptOrder The sales fulfillment processing can now begin…
  84. 84. @jeppec Events An Event is non-prescriptive of what should happen in other parts of the system. It leaves this open to the recipients, so that they themselves determine what to do based on occurrence of the event. Events always carry a name in its past-tense form: OrderWasAccepted, OrderHasShipped, CustomerWasReimbursed Other qualities • Immutable, i.e. content cannot be changed • Always carries the ID of the Aggregate it relates to • An event can and will typically will be published to multiple consumers. • The publisher of the event does not know who the recipients are • And it doesn’t know what the recipients intend to do with the event “An Event describes something that HAS happened”
  85. 85. @jeppec Choreographed Event Driven Processes Sales Service Order Accepted Billing Service Order Fulfilment (Saga/ Process-Manager) Shipping Service Online Ordering System MessageChannel(e.g.aTopic) Order Accepted Order Accepted Customer Billed Customer Billed Order Approved Order Approved Works as a Finite State Machine (WorkFlow) handling the life cycle of Shipping and thereby forms a very central new Aggregate in the System
  86. 86. @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
  87. 87. @jeppec
  88. 88. @jeppec Service Microservices 1..* Is implemented by A Service is the technical authority of a specific Bounded-Context/Business Capability e.g. Sales, Shipping, Billing Service vs Microservices
  89. 89. @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
  90. 90. @jeppec A Service represents a logical boundary 90 Service Microservice Microservice Microservice Microservice
  91. 91. @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)
  92. 92. @jeppec Microservices is an architectural style 92
  93. 93. @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)
  94. 94. @jeppec There’s cost in deploying 1000’s of microservices (or 100.000’s serverless functions) 94
  95. 95. @jeppec Autonomous Components Not everything needs to be individually deployable 95
  96. 96. @jeppec This means they CAN, but they don’t HAVE to be deployed individually. Design for Distribution But take advantage of locality
  97. 97. @jeppec Let’s be even more pragmatic In which case we allow other services to call them using local calls 97
  98. 98. @jeppec AC 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.registerAxonReplayableTopicPublisher(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) -> { }); } }
  99. 99. @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
  100. 100. @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
  101. 101. @jeppec AC, autonomy and “shared” service data Service DB DB Autonomous Component Autonomous Component Autonomous Component Autonomous Component DB
  102. 102. @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!
  103. 103. @jeppec How do we bring things together for our users without introducing unnecessary coupling? 103
  104. 104. @jeppec Let’s look at Applications
  105. 105. @jeppec iOS Home Banking Customer information Legal and contract information Accounts
  106. 106. @jeppec iOS Home banking Customer information Legal and contract information Accounts Credit card Mortgage loans Web banking portal Bank Back-office application
  107. 107. @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
  108. 108. @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
  109. 109. @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
  110. 110. @jeppec 110
  111. 111. @jeppec 111
  112. 112. @jeppec Composite page example Page Context: {id: ISBN-10 0-321-83457-7 } Images Books Reviews Pricing Inventory OthersAlsoBought Pricing Reviews Books Images Books
  113. 113. @jeppec A Service represents a logical boundary 113 Service Autonomous Component Autonomous Component Adapter UI component
  114. 114. @jeppec An Application is the plate where Components are co-deployed 114 Sales service components Inventory service components …
  115. 115. @jeppec An UI is composed of widgets from different services 115
  116. 116. @jeppec Widget Widget Page Widget Widget Widget Widget • Overall structure of the page is “owned” by the application. • Each widget is independent Composite page layout Widget Widget Widget
  117. 117. @jeppec 117
  118. 118. @jeppec Page Rendering Example Page Ctrl Sales Service UI Broker Customer Service Pricing Service Product Service Page Widget Ctrl Widget Ctrl Widget Ctrl Widget Ctrl Widget Ctrl Widget Ctrl Widget Ctrl Widget Ctrl 1. Backend API Backend API Backend API Backend API 2. 3. 4. 5. 5. 6. 7.7. 7. 7. 5. 8. 8. 8. 8.
  119. 119. @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); } }
  120. 120. @jeppec How do you search across services? Product Feature Product Price Producer Product Price
  121. 121. @jeppec Matching Product Id’s SearchEngine IFilterProducts<ProductId> How do you search across services? Product Feature Product Price Producer Product Price Filter Product Name Filter Produce Price Filter Stock status
  122. 122. @jeppec 122
  123. 123. @jeppec Distributed Bus Topics Queues Distributed per Service EventBus Distributed Notifications Distributed Broadcast Distributed SingleInstanceTask
  124. 124. @jeppec pricing_engine_ac (deployed on 10.25.26.102) pricing_engine_ac (deployed on 10.25.26.101) Bus Bus Bus Bus inventory_ac (deployed on 10.25.26.104) inventory_ac (deployed on 10.25.26.103) Federated Bus
  125. 125. @jeppec CreateOrder Sales Service : Orders_Ac Webshop Application Customer Service : Customer_Agreements_Ac OrderCreated OrderCreatedEvent Publish CreateCustomerAgreement OrderEvents <<Topic>> OrderCreatedEvent
  126. 126. @jeppec Client handled subscriptions • Highly resilient pattern for an Event Driven Architecture that’s backed by Event-Sourced AC’s • In this model the publisher of the Events is responsible for the durability of all its Events, typically to an EventStore/EventLog. • Each client (subscriber) maintains durable information of the last event it has received from each publisher. • When ever the client starts up it makes a subscription to the publisher where it states from which point in time it wants events published/streamed to it. • This effectively means that publisher can remain simple and the client (subscriber) can remain simple and we don’t need additional sophisticated broker infrastructure such as Kafka+ZooKeeper.
  127. 127. @jeppec Client handled subscriptions Publisher Subscriber A Local storage EventStore Subscriber B Local storage Topic Subscription Topic Subscription TopicSubscriptionHandler TopicSubscriptionHandler EventEvent Event Event EventBus Event Event
  128. 128. @jeppec 5 Microservices Do’s • Identify Bounded Contexts (or Business Capabilities) and split your services according to them. A service is owned by one team that builds and runs the service. This gives you proper business and IT alignment and allows pin point accuracy with regards to spending money to solve problems. • Spend time to understand the business processes and the domain. At first you must go slow to go fast. Building microservices properly takes time and is not trivial. Identify how likely things are to change and what things change together. • Focus on the business side effects - also know as the Events and make them a first class principle. Avoid RPC/REST/Request-Response between Services - events are the API. • Consider building Composite Applications to decouple services further. An application is owned by a dedicated team, but may borrow developers from service teams. • Learn from history. Don’t repeat the mistakes that gave (misapplied) SOA a bad name. Also, microservice might not be as small as you think - we need low coupling as well as high cohesion :)
  129. 129. @jeppec 5 Microservices Don’ts • Do not introduce a network boundary as an excuse to write better code - many have troubles with poorly modularized monoliths and believe that introducing network between modules magically solves the problem. If you don’t change your thinking and design, you will end up with a distributed monolith, which has all the disadvantages of a monolith, the disadvantages of a distributed system and none of the advantages of microservices • Don't split the atom! Distributed Transactions are never easy. Learn about the CAP theorem and avoid Request/Response API’s between Services. • Don't fall into the trap of “Not my problem”. When working on isolated code bases teams can loose sight of the big picture. • Identify the bottlenecks and possible solutions before deciding to split a problem into one or more microservices. There’s nothing that guarantees your microservice scales better than your monolith. • Don't do big bang rewrites. Move towards microservices gradually while focusing on functional areas that can replace or support the old monolith. Don’t rewrite core business while being new to microservices.
  130. 130. Thanks :) Blog: https://cramonblog.wordpress.com/ Homepage: http://cloudcreate.dk/ Twitter: @jeppec

×