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

Moduar Monolith @Codecamp 2023

Victor Rentea
November 17, 2023

Moduar Monolith @Codecamp 2023

Victor Rentea

November 17, 2023
Tweet

More Decks by Victor Rentea

Other Decks in Technology

Transcript

  1. 👉 victorrentea.ro/training-offer Hi, I'm Victor Rentea 🇷🇴 PhD(CS) Java Champion,

    17 years of code, code, code, code, code.... Consultant & Trainer: 5000 developers of 100+ companies in EU: ❤ Clean Code, Architecture, Unit Tes3ng 🛠 Spring, Hibernate, Reactor ⚡ Java Performance, Secure Coding 🔐 Conference Speaker – many conferences talks on YouTube Founder of European SoLware CraLers (5500+ members) 🔥 Free monthly webinars, 1 hour a9er work 👉 victorrentea.ro/community Past events on my channel: youtube.com/vrentea Father of 👧👦, host of a 🐈, weekend gardener 🌼 h"ps://VictorRentea.ro
  2. 4 VictorRentea.ro a training by The Monolith Tangled highly-coupled code

    Full of dirty fixes Slow and risky to change Craving for refactoring, but lacking unit tests The architecture of many successful systems in produc@on today aka Big Ball of Mud
  3. 6 © VictorRentea.ro a training by A large project is

    more likely to suffer from internal coupling (ie. domain dilu6on, scope creep) than from coupling to external APIs and Libraries Elders Wisdom Focus of tradi6onal Concentric Architectures (Clean, Onion, Hexagonal, Ports-Adapters)
  4. 7 © VictorRentea.ro a training by Microservices🌈 ü Faster Time-to-Market

    ⭐ ü Smaller Teams (Two-Pizza-sized) ü Improved Scalability ü Fault Tolerance ü Programming Language Agnos?c ü Data Security Microservice 💰 Premium 💰 - Network Latency - Timeout/Retry - Idempotency - Load balancing - Rate Limiter - Bulkhead - Circuit Breaker/503 - Distributed cache - Log aggregaGon - Request tracing - Message queues - k8s, Docker - Mature DevOps culture
  5. 8 VictorRentea.ro a training by 1) Big-Bang Rewrite - Start

    from scratch, re-specifying all behavior - New features in old system: delay or implement twice - 20-30% success rate - Likely to end up with a Distributed Monolith 😱 2) Strangler-Fig Pa4ern - Implement new features in fresh microservices - Con6nuously strip bits of func6onality from the monolith 3) Refactor to Modules > Extract 🌈 - Decouple logic and data in the same monolithic codebase From a Legacy Monolith💀 to Microservices🌈 Highly-coupled Distributed Systems
  6. 9 VictorRentea.ro a training by Modular Monolith is a safe

    Transi8oning Step from a Legacy Monolith è Microservices
  7. 11 VictorRentea.ro a training by What's faster to build from

    scratch? A Monolith or Microservices But coupling eventually starts slowing us down
  8. 12 VictorRentea.ro a training by Produc@vity Func@onal Complexity (Time) Microservices

    as complexity accumulates, produc6vity starts to drop overhead of managing distributed systems reduces ini6al produc6vity the decreased coupling of microservices outweighs their governance overhead Produc2vity years Monolith But I'm going to build a complex system!
  9. 13 VictorRentea.ro a training by "You shouldn't start a new

    project with microservices, even if you're sure your application will be big enough to make it worthwhile." - Martin Fowler h-ps://marKnfowler.com/bliki/MonolithFirst.html (2015) Start simple and address the natural bottlenecks of the system (functional/technical).
  10. 16 VictorRentea.ro a training by What if we could have

    the best of both worlds? Physical architecture of a Monolith Logical architecture of Microservices Ability to easy extract a Microservice out when necessary
  11. 18 VictorRentea.ro a training by Legacy Monolith Microservices Database eShop

    ApplicaGon Catalog Microservice Catalog DB Orders Microservice Orders DB REST REST/MQ Payment Microservice Payment DB Customer Microservice Customer DB vs
  12. 19 VictorRentea.ro a training by Modular Monolith Database E-Shop Modular

    Monolith ApplicaGon Catalog Module Orders Module Payment Module Customer Module
  13. 20 VictorRentea.ro a training by Life in a Modulith The

    complexity of the project is split in decoupled modules managed by separate teams 🎉
  14. 22 VictorRentea.ro a training by Think of a module as

    a stand-alone logical applica/on (including its own frontend)
  15. 24 VictorRentea.ro a training by Internal Architecture of a Module

    Layered Architecture Presenta6on / API Service Repository
  16. 25 VictorRentea.ro a training by Internal Architecture of a Module

    Layered Architecture Clean, Pragma/c* Architecture Domain * Avoid over-engineering: h"ps://www.youtube.com/watch?v=ewe68u1v6bo
  17. 26 VictorRentea.ro a training by Internal Architecture of a Module

    Layered Architecture Clean, Pragma/c* Architecture Ver/cal Slice Architecture Presenta6on / API Service Repository Place Order Es6mate Shipping Date
  18. 28 © VictorRentea.ro a training by Architecture is the art

    of drawing lines (boundaries) Elders Wisdom
  19. 29 VictorRentea.ro a training by .controller .service .repo .infra com.myorg.myapp

    .order .product Top Packages Reflec8ng Technical Layers (tradi'onal style) .entity .order .product To keep packages small, we introduce sub-packages
  20. 30 VictorRentea.ro a training by .service com.myorg.myapp .order .product .service

    The Screaming Architecture Top-level packages reflect your domain structure .entity .repo … … separate modules h"ps://blog.cleancoder.com/uncle-bob/2011/09/30/Screaming-Architecture.html
  21. 31 VictorRentea.ro a training by .order .product .fulfillment .catalog .invoice

    .invoicing Group by Business Capability (what value it brings the users) Group by Data Concept Module Names
  22. 32 VictorRentea.ro a training by Organize by Capability supports beIer

    the complexity Pricing Catalog Customer • customer first name • customer last name • product name • product description • customer status • product price class Customer { firstName lastName status !!... } class Product { name description price !!... }
  23. 33 VictorRentea.ro a training by A Module* is NOT: •

    Just Behavior Example: calcula6on, valida6on • Just CRUD Data Example: Country, Tenant, Clinic * the same applies for "Microservice" Microservices: configura6on or en6ty microservice CountryRepo in the 'shared' module
  24. 34 VictorRentea.ro a training by A Module* is the technical

    authority for a business capability .product .catalog * the same applies for "Microservice"
  25. 35 VictorRentea.ro a training by The boundary within which a

    Domain Model applies The smaller the boundary, the more useful the model. Bounded Context 2003
  26. 36 VictorRentea.ro a training by How Big should a Module*

    be? * the same applies for "Microservice" As small as possible!
  27. 39 VictorRentea.ro a training by The Fallacy of Nano-Modules* h)ps://vladikk.com/2020/04/09/untangling-microservices/

    * the same applies for "Microservice" Global Complexity of integraGng all the APIs Local Complexity of a single module High Cohesion, Low Coupling
  28. 40 VictorRentea.ro a training by Be brave and Keep It

    Super Simple When Complexity Grows > Extract it Evolutionary Architecture
  29. 41 VictorRentea.ro a training by Module A @Test !// unit

    test on CI public void independentSubdomains() { slices().matching("!..myapp.(*)!..*") .should().notDependOnEachOther() .ignoreDependency(resideInAnyPackage( "!..shared!..", "!..api!..")) .check(new ClassFileImporter(). importPackages("com.myapp")); } 2) Communica2on between Modules The internals of a module should never be accessed from another module Each Module exposes a Public API that other modules can reference Public API events calls 1. Compiler-enforced Separate CompilaGon Units (eg Maven modules) 2. Unit Tests on CI Code Analysis, eg ArchUnit: Part of the Public API can be exposed as External API to remote apps (eg via REST, MQ) External API
  30. 42 VictorRentea.ro a training by Module CommunicaJon via Method Calls

    calls Extremely simple Fast, in-memory calls (no networking) ⚠ Methods called and objects involved must be part of the Public API
  31. 43 VictorRentea.ro a training by ⚠ Published Events must be

    part of the Public API J Decoupled: publisher unaware of listeners (poten@ally mul@ple) J Poten@ally async J Poten@ally persisted L Not suitable for request-reply interac@on L Naviga@ng code is harder (than a method call) Event Types: No@fica@on {id}, or Heavy-Events {state} events Module CommunicaJon via Events / Messages
  32. 44 VictorRentea.ro a training by Cyclic Dependencies between Modules A

    B call call Build fails if modules are separate compila@on units (eg. Maven/Gradle modules) <dependency> <dependency>
  33. 45 VictorRentea.ro a training by api (shared) A B O

    orchestrator Keep Orchestra@on Up Just fix the build, allow the ó calls A B A-api B-api Extract API modules run'me calls Facade keep a coarse grained API, eg for a monolith site Fixing Cyclic Dependencies between Modules microservices: N/A microservices: events on queue microservices: interdependent microservices microservices: api gateway/bff/saga microservices: shared lib/3rd service microservices: merge? ❤ AB Merge Modules Tight Coupling (eg dozens of links) wrong boundaries? Using Dependency Inversion B can let A implement logic, without depending on A A B ç event call Publish Events (in-mem) ⭐Decoupled A B C commons Push Commons Down A B implements è call Dependency Inversion ⭐Decoupled AProviderImpl runKme call AProvider Module A must react to changes in B Technical Stuff Only send email countryRepo audit, ... uSls
  34. 46 VictorRentea.ro a training by A Surface of a Module

    publish events call interface implementa-on B command query (a) no-fica-on {id} (b) Heavy-Event {state} listen to events External API Public API
  35. 47 VictorRentea.ro a training by 3) Module Data Independence Every

    module is responsible for its own data ⚠ A Module should not query the tables of another module (breaks encapsula@on) Instead, ask for that data via the Public API
  36. 48 VictorRentea.ro a training by Module Data Isola2on Levels No

    IsolaGon: Any module can freely read/write any table Write IsolaGon: A table is updated by ONE module, but can be read by other modules Table IsolaGon⭐: A module has exclusive access to its tables (usually separate schemas) Consistency IsolaGon - tables of different modules: (a) cannot share a Foreign Key, and (b) are never updated in the same DB transac@on Separate database instance / module Different database types, eg PostgresSQL / MongoDB Before extrac@ng a microservice
  37. 49 VictorRentea.ro a training by Tes8ng a Modulith End-to-end Tests

    are easier in a monolith Module Tests Integra0on tes0ng an Module in isola0on - mock public APIs of other modules - mock event bus è Spring Modulith project h4ps://spring.io/projects/spring-modulith
  38. 50 VictorRentea.ro a training by Modulith – Lessons Learned Ø

    Invest more @me to clarify module boundaries Ø Consider merging highly-coupled modules Ø Don't sacrifice consistency too early Ø Carefully design how data is shared between modules Ø Don't leak internal classes via module's Public API Ø Monitor architecture fitness func@ons using code analysis tools
  39. 51 VictorRentea.ro a training by •Migrating legacy monoliths eg. an

    existing large-scale banking platform monolith that needs to split into microservices, but isn't ready to separate into completely independent services. •A greenfield implementation eg. a new peer-to-peer lending platform in the early stages of growing into a full suite of financial services •A system with a low-moderate scale eg. a movie ticket booking platform that serves several thousand users and handles a few million transactions per week. •Non-complex software platforms eg. a notes/documents syncing and management platform for consumer apps. When to choose a Modulith? When to move to Microservices? •High Delivery Rate ? eg. the company decides investing in shipping to self-collect boxes on the street, and new versions are deployed weekly. •Scalability eg. the endpoint selecting the ad to insert in a live stream expected to take 1k-10k requests/second. •Fault-tolerance eg. in the same ad-insert solution, if the management part fails, the ads still have to be inserted •Different Programming Language eg. the senior developers of sales department are using C# while the rest of the teams use Java. Oh, and Kotlin rocks!🤘 •Security eg. customer management has to be audited for GDPR compliance regarding PII information.
  40. 52 VictorRentea.ro a training by But remember, The Skills of

    the Team will outweigh any monolith/microservice choice A great team will build a great project whatever architectural style you choose #investInPeople
  41. thank you [email protected] ♦ ♦ @victorrentea ♦ VictorRentea.ro victorrentea.ro/community Want

    more? Register for my upcoming deep dive webinar on Architectures on May 29-30 at h"ps://clean.re For a company workshop see victorrentea.ro/training-offer
  42. 54 VictorRentea.ro a training by § Ugly (Successful) Monolith☠ -

    "It works > Ship it now, refactor later" for 5-25 years § Domain-Driven Design (Eric Evans, 2003) link - Design Rich Domain Model for complex problems; - Split soluKon in Bounded Context § Onion/Clean Architecture (Jeffrey Palermo, Uncle Bob 2008) link - Keep core Domain Logic agnosKc from UI, APIs, DB, frameworks (by dep. inversion) § PragmaQc Onion link - Merge applicaKon with infrastructure, evolve layers as needed, tolerate ORM on Domain Model § Microservices (2011) - Loosely coupled, independent business capabiliKes deployed separately § Distributed Monolith☠ link - Tightly coupled microservices due to premature, too fine-grained breakdown § VerQcal Slice Architecture (Jimmy Bogard, 2018) link - Group code by feature, not by technical layer § Modular Monolith, aka Modulith (Simon Brown, 2018) - Implement business capabiliKes as loosely coupled modules in a single deployment unit Overview of Architecture Styles