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.

Avoiding the domino effect in our [micro]services (SOLID at macro-design level)

683 views

Published on

How can we apply SOLID principles to a macro-design level in our [micro]services architectures?

In this talk we will see a problem-solution approach on how we deal with different kinds of load for our different services in order to avoid a domino effect while having peaks of request in one of our services. We'll do so using Domain Events and Message Queues such as RabbitMQ and AWS SNS-SQS.

Spanish resources:
* Hexagonal Architecture course: https://pro.codely.tv/library/arquitectura-hexagonal/66748/about/
* CQRS course: https://pro.codely.tv/library/cqrs-command-query-responsibility-segregation-3719e4aa/62554/about/
* HTTP API with Scala course: https://pro.codely.tv/library/api-http-con-scala-y-akka/66747/about/
* Testing in CQRS architectures talk: https://www.youtube.com/watch?v=cw6Va1ZW7iI
* We broke up with the monolith, and started dating event sourcing slides: https://www.slideshare.net/JavierCane/we-broke-up-with-the-monolith-and-started-dating-eventsourcing-symfonycat

English resources:
* The anatomy of Domain Event: blog.arkency.com/2016/05/the-anatomy-of-domain-event/
* Versioning in an Event Sourced System book: https://leanpub.com/esversioning
* RabbitMQ Simulator: tryrabbitmq.com
* A Series of Fortunate Events slides: https://www.slideshare.net/matthiasnoback/a-series-of-fortunate-events-symfony-camp-sweden-2014

Published in: Software
  • Be the first to comment

Avoiding the domino effect in our [micro]services (SOLID at macro-design level)

  1. 1. Avoiding the domino effect in our [micro]services Raising the DIP & OCP to a macro-architecture level
  2. 2. @JavierCane@rafaoe Who we are Intro
  3. 3. Goals ! Illustrate how to isolate our [micro]services avoiding the domino effect " Show the similarities between the DIP & OCP applied to micro and macro design levels Intro
  4. 4. User story
  5. 5. Problem: Domino Effect
  6. 6. Stage 1: The Monolith Problem: Domino Effect
  7. 7. Stage 1: The Monolith THE MONOLITH GET /users/x PUT /videos/x DB { "id": “some-uuid", "name": "Vicenç", "total_videos_created": 1 }
  8. 8. Stage 1: The Monolith THE MONOLITH DB GET /users/x PUT /videos/xx1000# $ { "id": “some-uuid", "name": "Vicenç", "total_videos_created": 1 }
  9. 9. Recap Stage 1: The Monolith If it’s a small-medium size application: % Easy to know how the system works % Quick to develop new features
 In any case: & Development scaling issues & Application scaling issues & Infrastructure scaling issues Stage 1: The Monolith
  10. 10. HATERS
  11. 11. Haters advisory " Assume we’ve actual needs to implement a [micro]services architecture: ' Multiple development teams ( Different needs that require different programming languages ) Different scaling needs for each service Introduction
  12. 12. Stage 2: The Microliths Problem: Domino Effect
  13. 13. Stage 1: The Monolith THE MONOLITH GET /users/x PUT /videos/x DB
  14. 14. USERS SERVICE GET /users/x PUT /videos/xVIDEOS SERVICE Stage 2: The Microliths DB
  15. 15. AKA Distributed Monolith * USERS SERVICE GET /users/x PUT /videos/xVIDEOS SERVICE Stage 2: The Microliths DB x1000# $
  16. 16. % Enable to develop applications in different ecosystems % Solve application scaling issues % Solve development scaling issues! (&DB schema) ☝ Not so easy to know how the system works & Infrastructure scaling issues Changelog Stage 2: The Microliths
  17. 17. Stage 2.1: Coupled Microliths Problem: Domino Effect
  18. 18. USERS SERVICE GET /users/x PUT /videos/xVIDEOS SERVICE Stage 2: The Microliths DB
  19. 19. USERS SERVICE DB GET /users/x PUT /videos/xVIDEOS SERVICE DB Stage 2.1: Coupled Microliths
  20. 20. USERS SERVICE DB GET /users/x PUT /videos/xVIDEOS SERVICE DB , Stage 2.1: Coupled Microliths x1000- $ { "id": “some-uuid", "name": "Vicenç", "total_videos_created": 1 }
  21. 21. USERS SERVICE DB GET /users/x PUT /videos/xVIDEOS SERVICE DB , Stage 2.1: Coupled Microliths x1000- $ { "id": “some-uuid", "name": "Vicenç", "total_videos_created": 1 }
  22. 22. USERS SERVICE - DB GET /users/x PUT /videos/xVIDEOS SERVICE DB , GET /videos
 ?user_id=x Stage 2.1: Coupled Microliths $ x1000 AKA Distributed Monolith *
  23. 23. % Solve infrastructure scaling issues % Even more development scaling possibilities (less coupling) & Scaling issues because of coupling between services & Communications between services latency & More work to do (SQL query vs. expose & consume HTTP endpoint) Changelog Stage 2.1: Coupled Microliths
  24. 24. 5
  25. 25. Do you remember… SOLID!
  26. 26. Stage 1: “The Monolith” Do you remember… SOLID!
  27. 27. import tv.codely.scala_http_api.module.video.infrastructure.MySqlVideoRepository final class VideoCreator(repository: MySqlVideoRepository) { def create(id: VideoId, title: VideoTitle): Unit = { val video = Video(id, title) repository.save(video) } } Monolithic Video Creator Use Case
  28. 28. import tv.codely.scala_http_api.module.video.infrastructure.MySqlVideoRepository final class VideoCreator(repository: MySqlVideoRepository) { def create(id: VideoId, title: VideoTitle): Unit = { val video = Video(id, title) repository.save(video) } } Monolithic Video Creator Use Case
  29. 29. Do you remember… SOLID! > Stage 1: “The Monolith” MySqlVideoRepository I VideoCreator
  30. 30. Highlights % Code easy to trace & Change tolerance (coupling between application services & infrastructure) Do you remember… SOLID! > Stage 1: “The Monolith”
  31. 31. Stage 2: DIP! Do you remember… SOLID!
  32. 32. import tv.codely.scala_http_api.module.video.infrastructure.MySqlVideoRepository final class VideoCreator(repository: MySqlVideoRepository) { def create(id: VideoId, title: VideoTitle): Unit = { val video = Video(id, title) repository.save(video) } } Monolithic Video Creator Use Case
  33. 33. import tv.codely.scala_http_api.module.video.domain.VideoRepository final class VideoCreator(repository: VideoRepository) { def create(id: VideoId, title: VideoTitle): Unit = { val video = Video(id, title) repository.save(video) } } DIP compliant Video Creator Use Case
  34. 34. trait VideoRepository { def save(video: Video): Future[Unit] } Video Repository Domain Contract
  35. 35. Do you remember… SOLID! > Stage 1: “The Monolith” MySqlVideoRepository I VideoCreator From:
  36. 36. I VideoCreator Do you remember… SOLID! > Stage 2: DIP! MySqlVideoRepository VideoRepository i To:
  37. 37. Changelog % Easy to add new implementations • Dependency Inversion Principle compliant • Open/Closed Principle compliant Do you remember… SOLID!
  38. 38. Stage 3: Hexagonal Architecture Do you remember… SOLID!
  39. 39. Infrastructure Application Domain Hexagonal architecture (DDD) Testing CQRS+DDD
  40. 40. Testing CQRS+DDDTesting CQRS+DDD > Flujo petición DDD+CQRS D A I VideoCreator MySqlVideoRepository VideoRepository i
  41. 41. Stage 4: CQRS Do you remember… SOLID!
  42. 42. Testing CQRS+DDDTesting CQRS+DDD > Flujo petición DDD+CQRS CreateVideoCommand VideoPostController D A I CommandBus i CreateVideoCommandHandler VideoCreator MySqlVideoRepository VideoRepository i
  43. 43. Testing CQRS+DDDTesting CQRS+DDD > Flujo petición DDD+CQRS Acceptance test COMMAND/QUERY CTRL REPOS MODELS SERVICES IMPLEMENTATION BUS HANDLER APP. SERVICE D A I Unit test Integration test
  44. 44. How do we apply this concept to our [micro]services? Do you remember… SOLID! From: I MySqlVideoRepositoryVideoCreator VideoCreator MySqlVideoRepository VideoRepository i To:
  45. 45. Solving the Domino effect Raising the DIP & OCP to a macro-architecture level
  46. 46. USERS SERVICE DB GET /users/x PUT /videos/xVIDEOS SERVICE DB GET /videos
 ?user_id=x Stage 2.1: Coupled Microliths AKA Distributed Monolith *
  47. 47. From: I Users ServiceVideos Service ??? ? To: Videos Service Users Service Solving the Domino Effect
  48. 48. From: I Users ServiceVideos Service video_created e To: Videos Service Users Service Solving the Domino Effect
  49. 49. USERS SERVICE DB GET /users/x PUT /videos/xVIDEOS SERVICE DB Subscribed to video_created e Publishes Solving the Domino Effect
  50. 50. USERS SERVICE DB GET /users/x PUT /videos/xVIDEOS SERVICE DB x1000 $, - . video_created e Publishes Subscribed to Solving the Domino Effect
  51. 51. % Less communication (blocking latency) % More reactiveness (Reactive Manifesto) % Scaling • Development (OCP!) • Infrastructure • Application Changelog - Wins Solving the Domino Effect
  52. 52. ☝ Eventual consistency ☝ Maintain videos information in Users service ☝ Handle duplicated events (idempotency) ☝ Handle events arriving disordered Changelog - New kind of issues Solving the Domino Effect
  53. 53. 5 9 I don’t know Rick…
  54. 54. Conclusions
  55. 55. To take away / SOLID principles can be applied at micro and macro-design levels 0 Think about your Domain Events as you Domain interfaces/contracts ! Inappropriate intimacy: Services exposing information just because of other services need it. Simplify your services by limiting their APIs. 1 Domain events as ACL. Useful while refactoring legacy systems. Conclusions
  56. 56. Wait! Do we need [micro]services in order to apply these concepts at macro-design level?
  57. 57. More info CodelyTV Pro Hexagonal Architecture course (Spanish) CodelyTV Pro CQRS course (Spanish) CodelyTV Pro Scala HTTP API course (Spanish) Testing CQRS talk (Spanish) We broke up with the monolith, and started dating #eventSourcing Versioning in an Event Sourced System RabbitMQ Simulator A Series of Fortunate Events The anatomy of Domain Event Conclusions
  58. 58. 2Vídeo resúmenes de los cursos3
  59. 59. Mini-demo time! https://github.com/CodelyTV/scala-http-api/ https://github.com/CodelyTV/cqrs-ddd-php-example
  60. 60. ¡Thanks! Tweet #BilboStack2018 = Raffle CodelyTV Pro subscription

×