Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DDD, necessary but insufficient: physical design principles for microservices

DDD, necessary but insufficient: physical design principles for microservices

When we design software using DDD, we primarily focus on creating models scoped by bounded contexts that define ubiquitous languages. We also structure the models and the elements they contain to be loosely coupled and highly cohesive. However, while (logical) design techniques such as DDD domain modeling concepts, loose coupling and high cohesion are essential for creating good software, they are insufficient when designing a microservice architecture. In particular, we must also consider other more physical constraints including team size; team, process and transaction boundaries; and the cost of communication over a network.

In this talk, I describe a set of physical design principles for organizing subdomains into microservices. You will learn about both principles that encourage finer-grained decomposition into services as well as those that discourage decomposition. I describe how to apply those principles to design a microservice architecture.

Chris Richardson

April 26, 2023
Tweet

More Decks by Chris Richardson

Other Decks in Technology

Transcript

  1. @crichardson DDD, necessary but insu ff i cient: physical design

    principles for microservices Chris Richardson Microservice architecture consultant and trainer Founder of the original CloudFoundry.com Author of POJOs in Action and Microservices Patterns Founder of Eventuate.io @crichardson [email protected] adopt.microservices.io Copyright © 2023. Chris Richardson Consulting, Inc. All rights reserved Loose coupling and high cohesion X v
  2. @crichardson Presentation goal Logical design principles are insuf fi cient

    when designing microservices Physical design principles are also required
  3. @crichardson Agenda Logical design: coupling and cohesion Overview of the

    microservice architecture Dark energy forces: encouraging decomposition Dark matter forces: resisting decomposition
  4. @crichardson Subdomain Package Class Method Field Software design: naming and

    organizing software elements Application Subdomain Package Class Method Field Organize software elements into a hierarchy so that change is easy
  5. @crichardson About (design-time) coupling Element A Element B Design-time coupling

    = Likelihood of needing to change for the same reason Tight coupling = frequently changing together
  6. @crichardson The problem of tight coupling Increases the scope of

    the change More to understand More to change Increases coupling between teams Conways law More coordination and communication between the teams Therefore Minimizing coupling is essential
  7. Examples of design techniques for loose coupling Implementation API Smaller

    Larger • Encapsulation • Information hiding • Dependency inversion principle • Interface Segregation principle • … Software element = iceberg
  8. @crichardson Cohesion: localizing unavoidable coupling Package X Class A Class

    B Class C coupled elements (e.g. classes) should have the same parent (e.g. package) Package Y Loosely coupled Cohesive element = tightly coupled sub-elements Class D • Common closure principle • Separation of concerns • … elsewhere
  9. @crichardson Bene fi ts of high cohesion Tightly coupled elements

    are together with same parent Loosely coupled elements are apart Elements unrelated to the change are elsewhere Less to understand when making a change Therefore Designing for high cohesion is essential
  10. @crichardson Attractive vs repulsive forces for grouping elements Element A

    Element B Coupling = Attraction Cohesion = Repulsion
  11. @crichardson Microservices are just another element in the hierarchy, right?

    Hint: not exactly Subdomain Package Class Application Subdomain Package Class Subdomain Service Method Field Method Field
  12. @crichardson Agenda Logical design: coupling and cohesion Overview of the

    microservice architecture Dark energy forces: encouraging decomposition Dark matter forces: resisting decomposition
  13. @crichardson Process: DevOps/Continuous Delivery & Deployment Organization: Network of small,

    loosely coupled, product teams Architecture Testable Deployable Loosely coupled Developing modern software IT must deliver software rapidly, frequently, reliably and sustainably. Supports Supports Measured by DORA metrics: • Deployment frequency • Lead time • Change failure rate • Time to restore service The monolithic architecture is sometimes an obstacle
  14. @crichardson API What’s a service…? Operations Event Publisher Commands Queries

    Synchronous REST/gRPC Asynchronous Messaging Events Event Subscriber API Client Invokes Operations Events Service Database Responsibilities Service Name
  15. @crichardson Runtime environment Infrastructure Git repository Application code Infrastructure code

    … what’s a service?… Application code Infrastructure code Deployment pipeline Deployable /executable Service instance Service instance Infrastructure
  16. @crichardson … what is a service? Service ≪subdomain≫ … ≪subdomain≫

    Order Management ≪subdomain≫ Customer Management Customer Team Order Team Ideally: One subdomain/team BUT Not always
  17. @crichardson Designing services using coupling and cohesion = not bad

    …. Service X Subdomain A Subdomain B Subdomain C Tightly coupled subdomains should be in the same service Service Y Loosely coupled Cohesive services = tightly coupled subdomains Subdomain D elsewhere
  18. @crichardson … but insuf fi cient ≪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://microservices.io/post/architecture/2023/03/26/dark-energy-dark-matter-force-descriptions.html Generate systemOperation()
  19. @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 … SystemOperation() Generates Forces that act on subdomains and determine grouping into services Two types of coupling! Mostly “physical concerns”
  20. @crichardson Designing an architecture = making trade-offs Con fl icting

    forces Therefore Some services/ operations will have an optimal design Others will be suboptimal but good enough Subdomain A «Aggregate» X Subdomain B «Aggregate» Y Service A Service B Attraction Simple, 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 Fine-grained services Monolith
  21. @crichardson Agenda Logical design: coupling and cohesion Overview of the

    microservice architecture Dark energy forces: encouraging decomposition Dark matter forces: resisting decomposition
  22. @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 Characteristics: • Resource requirements • Regulations, e.g. SaMD/PCI • Business criticality/tier • Security, e.g. PII, … • DDD core/supporting/generic • ... Designing cohesive services might help but is not guaranteed to resolve these forces
  23. @crichardson Simpler components/services Service Service Service Subdomain A Subdomain A

    Subdomain B Subdomain B More complex service: Dependencies, and runtime behavior Simpler services: easier to understand, develop, test, … versus
  24. @crichardson Team autonomy = service per team Service Service Service

    Subdomain A Subdomain A Subdomain B Subdomain B Coordination required Build, test and deploy independently vs. Team A Team B Team A Team B
  25. @crichardson Fast deployment pipeline: short lead time @mipsytipsy https://speakerdeck.com/charity/cd?slide=17 Service

    Subdomain Subdomain Service Subdomain Shorter lead time Simpler build Longer lead time More complex build* * Accelerate build/test: • Merge queue • Incremental testing through DIP and ISP • Parallelization/clustered builds • Selective test execution
  26. @crichardson Support multiple technology stacks: per-subdomain Service Python Service Java

    Service JVM Subdomain A Subdomain A Subdomain B Subdomain B Single technology stack Separate technology stacks Right tool for the job versus
  27. @crichardson Support multiple technology stacks: incremental upgrades Need to periodically

    upgrade each component in order to keep its technology stack current A component must be upgraded completely - not partially Task size ∝ complexity(component) The business often resists large tasks that don’t implement features Therefore Separate subdomains to reduce service upgrade effort
  28. @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
  29. @crichardson Cost effective scaling Service Service Service Subdomain A Subdomain

    A Subdomain B Subdomain B versus CPU MEM GPU Scale together • Wasteful • Costly CPU MEM GPU Scale separately • Ef fi cient • Cheaper Load Load Load Load EC2: p4d.24xlarge EC2: p4d.24xlarge EC2: m5.24xlarge 8x cost!
  30. @crichardson Example: Segregate by business criticality Service Service Service Payment

    Processing Payment Processing Merchant management Merchant management Shared infrastructure Risk of interference Separate infrastructure Isolated vs. chargeCard() 2.9% + 30c/ request Revenue loss and penalties chargeCard() Critical Important
  31. @crichardson Segregate regulated software Service Service Service SaMD Subdomain SaMD

    Subdomain Other Subdomain Other Subdomain ISO 13485 ISO/IEC 62304 ISO 13485 ISO/IEC 62304 DevOps Slower Faster
  32. @crichardson Agenda Logical design: coupling and cohesion Overview of the

    microservice architecture Dark energy forces: encouraging decomposition Dark matter forces: resisting decomposition
  33. @crichardson Dark matter attractive forces 㱺 subdomains in same service

    https://microservices.io/post/architecture/2023/03/26/dark-energy-dark-matter-force-descriptions.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 Attractive dark matter forces SystemOperation() Generates ✅ Less cohesive services
  34. @crichardson Customer Service Customer Subdomain Order Service Minimize design time

    coupling: avoid expensive lockstep changes Order Subdomain For zero-downtime deployments: 1. Change biz logic + Add new version of API 2. Migrate clients to new API 3. Remove old API Multiple commits
  35. @crichardson Code repository Order Service Customer Subdomain Eliminate tight design

    time coupling between services Order Subdomain Customer Service Customer Subdomain Order Service Order Subdomain OR OK: Same repository Best: Package together But deployments aren’t atomic: API evolution issues
  36. @crichardson Simple interactions Create Order() Service Subdomain A Subdomain B

    Service B Service A Subdomain A Subdomain B Create Order() Complex distributed operation Simple local operation: easier to understand, troubleshoot, … vs.
  37. @crichardson Ef fi cient interactions Create Order() Service Subdomain A

    Subdomain B Service B Service A Subdomain A Subdomain B Create Order() Network latency, limited bandwidth In-memory, fast! vs. Must satisfy SLOs
  38. @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
  39. @crichardson Challenges of eventual consistency Operation = sequence of local

    ACID transactions About commands Typically implemented using the Saga pattern Sagas are ACD - lack Isolation due interleaved execution Application must use countermeasures to implement Isolation About queries Implemented using API Composition or CQRS Query can return inconsistent results
  40. @crichardson Minimize runtime coupling Runtime coupling between service A and

    B is the degree to which the availability of service A is affected by the availability of service B Order Service Customer Service POST /orders 1 PUT /customers/id Response 4 2 3 Tight runtime-coupling: lower availability ID Outcome
  41. @crichardson Minimize runtime coupling System Operation() Service Subdomain A Subdomain

    B Service B Service A Subdomain A Subdomain B System Operation() Risk of runtime coupling, e.g. not meeting SLOs No runtime coupling: higher availability, lower latency vs. Must satisfy SLOs
  42. @crichardson Summary Loose coupling and high cohesion are important microservice

    design goals Using DDD to de fi ne subdomains/bounded contexts is valuable BUT You must also consider the dark energy and dark matter forces Dark energy forces Encourage decomposition Might increase design-time coupling Dark matter forces: Resist decomposition Includes minimize design-time coupling Might reduce service cohesion https://www.nasa.gov/feature/goddard/2019/nasa-s-james-webb-space-telescope-has-been-assembled-for-the- fi rst-time 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 … SystemOperation() Generates Forces that act on subdomains and determine grouping into services