SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.
SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.
Successfully reported this slideshow.
Activate your 14 day free trial to unlock unlimited reading.
Avoiding the domino effect in our [micro]services (SOLID at macro-design level)
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
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
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
7.
Stage 1: The Monolith
THE MONOLITH
GET /users/x PUT /videos/x
DB
{
"id": “some-uuid",
"name": "Vicenç",
"total_videos_created": 1
}
8.
Stage 1: The Monolith
THE MONOLITH
DB
GET /users/x PUT /videos/xx1000#
$
{
"id": “some-uuid",
"name": "Vicenç",
"total_videos_created": 1
}
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
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.
Stage 2: The Microliths
Problem: Domino Effect
13.
Stage 1: The Monolith
THE MONOLITH
GET /users/x PUT /videos/x
DB
14.
USERS
SERVICE
GET /users/x PUT /videos/xVIDEOS
SERVICE
Stage 2: The Microliths
DB
15.
AKA Distributed Monolith *
USERS
SERVICE
GET /users/x PUT /videos/xVIDEOS
SERVICE
Stage 2: The Microliths
DB
x1000#
$
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
18.
USERS
SERVICE
GET /users/x PUT /videos/xVIDEOS
SERVICE
Stage 2: The Microliths
DB
19.
USERS
SERVICE
DB
GET /users/x PUT /videos/xVIDEOS
SERVICE
DB
Stage 2.1: Coupled Microliths
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.
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.
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.
% 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
26.
Stage 1: “The Monolith”
Do you remember… SOLID!
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.
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.
Do you remember… SOLID! > Stage 1: “The Monolith”
MySqlVideoRepository
I
VideoCreator
30.
Highlights
% Code easy to trace
& Change tolerance (coupling between application services & infrastructure)
Do you remember… SOLID! > Stage 1: “The Monolith”
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.
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
42.
Testing CQRS+DDDTesting CQRS+DDD > Flujo petición DDD+CQRS
CreateVideoCommand
VideoPostController
D
A
I
CommandBus
i
CreateVideoCommandHandler
VideoCreator
MySqlVideoRepository
VideoRepository
i
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.
How do we apply this concept to our [micro]services?
Do you remember… SOLID!
From:
I
MySqlVideoRepositoryVideoCreator
VideoCreator
MySqlVideoRepository
VideoRepository
i
To:
45.
Solving the Domino effect
Raising the DIP & OCP to a macro-architecture level
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.
From:
I
Users ServiceVideos Service
???
?
To:
Videos Service
Users Service
Solving the Domino Effect
48.
From:
I
Users ServiceVideos Service
video_created
e
To:
Videos Service
Users Service
Solving the Domino Effect
49.
USERS
SERVICE
DB
GET /users/x PUT /videos/xVIDEOS
SERVICE
DB
Subscribed to
video_created
e
Publishes
Solving the Domino Effect
50.
USERS
SERVICE
DB
GET /users/x PUT /videos/xVIDEOS
SERVICE
DB
x1000
$,
-
.
video_created
e
Publishes
Subscribed to
Solving the Domino Effect
51.
% Less communication (blocking latency)
% More reactiveness (Reactive Manifesto)
% Scaling
• Development (OCP!)
• Infrastructure
• Application
Changelog - Wins
Solving the Domino Effect
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
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.
Wait!
Do we need [micro]services in
order to apply these concepts
at macro-design level?
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