most software projects
used to be built using a monolithic
architecture approach
these big apps would render websites
talk to the databases
stream data and contain all of the
business logic inside
over time software teams realized that
these apps became way too complex
they were difficult to maintain and
releases took forever to deploy
everything had to be coordinated between
different teams
and every change had to be tightly
controlled
in essence maintaining a monolith had
substantially slowed down development
speed
as a result a better way of developing
maintaining
and deploying software was invented
in essence the better way was to take
that big monolith
and break it down into smaller
self-contained
units called microservices
each unit would have its own context of
execution
would have its own public api and would
represent a specific
business logic a development team would
usually own
one or multiple units the idea was that
each microservice would evolve
independently of each other
which would increase the speed of
development
the new microservices architecture
assumed that each individual unit
would have to talk to other units within
the application
which means that units had to send
requests
and receive responses from other
microservices
most of these lines of communication
were implemented
using rest apis this means that
there is a rest endpoint which reads a
json file
that requires validation of a specific
request
such as a new product order request
this communication method worked great
for a while but
we started to discover the problem with
this model
the first issue was related to the
synchronous nature of the
request response communication which led
to tight
point-to-point coupling between the
services
this made scaling of the new
architecture challenging
in fact some developers started to call
this model
a distributed monolith which meant that
the teams
would still have to tightly coordinate
deployment efforts of the big band
releases another side effect of this
model
was that some teams made a mistake of
exposing
too many of the microservices to their
customers
which led to a point when evolving those
microservices became extremely
challenging
the other problem was that one had to be
very skillful at
architecting microservice environments
and very few teams
got it right the very first time a lot
of teams struggled with the
responsibility issue
trying to understand who is responsible
for what
the whole point of microservices was
that each
unit was only responsible for itself
but in reality teams had to heavily
coordinate their development efforts
in order to keep the products working
still another issue was related to
adding new microservices
into existing architecture the problem
with adding a new microservice
was that the team behind it faced a
bad circular logic problem the team
can't prove that a new microservice
is of value to other teams because no
one is using it
and the team can convince other teams to
use it because it cannot prove
its value
finally a lot of software teams realize
that
using http and json as means of
communication
especially when the application requires
high bandwidth communication
is actually pretty slow inefficient and
compute intensive
fortunately most of these issues have
now been addressed
and appropriate solutions have been put
in place
these solutions are related to several
specific patterns
that form today's best practices of
building
scalable microservices architectures
the first pattern that is very useful in
the context of the microservices
architecture
is the api gateway
this pattern is helpful in addressing
the issue of exposing
too many microservices to the customers
the way it works is that you want to
place the api gateway
in front of the microservices therefore
the clients will know only about the api
gateway
while the rest of the communication
pipes will be hidden from them
instead of every microservice in the
system performing the functions of api
authentication request response logging
and throttling having an api gateway
doing these functions upfront
will add a lot of value clients calling
your microservices will connect to the
api
gateway instead of directly calling your
service
this is even more necessary when a third
party is accessing your service
as you can throttle the incoming traffic
and reject
unauthorized requests from the api
gateway before they reach your
microservice
you can also choose to have a separate
api gateway that accepts
traffic from external networks the
second pattern that helps scale and run
microservices smoothly
is the service mesh which is a software
driven approach to routing
and segmentation the goal is to solve
the networking and security challenges
of operating microservices and cloud
infrastructure
service mesh solutions bring additional
benefits such as failure handling
retries and network observability in
essence
service mesh is the distributed internal
api gateway
if you look at the standard api gateway
it operates within the context of the
north
south traffic this is the traffic that
is heading in
or comes outside of your network and it
goes through the api gateway all the way
down to the individual
microservices we want to take this
useful
north-south traffic and apply to what we
call
east-west traffic the east-west traffic
is the traffic among the various
microservices
this traffic is considered to be
distributed compared to the centralized
north-south traffic
the idea here is to let the centralized
functions of routing
logging and rate limiting to operate
within the
distributed fashion the way we
accomplish this task is by utilizing
so-called
side cars this sidecar design pattern
has been
recently gaining popularity and wider
adoption within the community
as a sidecar is attached to a motorcycle
similarly
in software architecture a sidecar is
attached to a parent microservice
and enhances its functionalities a
sidecar is loosely coupled with the main
microservice
the goal of the sidecar design is to
reduce the complexity
by abstracting the common
functionalities to a different layer
besides this approach reduces code
duplication
since you do not need to write
configuration code inside
each microservice finally it provides
loose coupling between application code
and the underlying platform
one way to think about the site cars is
to view them as libraries that grow
their own environments
the idea is that you can deploy these
sidecars next to every microservice and
unlike the library
it is language agnostic one can write a
sidecar in python
and deployed next to the microservices
written in java rust
go or php this way all of these separate
microservices can get the same sidecar
which often reduces the overhead related
to the organizations trying to maintain
microservices in various different
languages the side cars are considered
to be
shared functionalities that can be
replicated across the entire application
the third pattern that is crucial in
designing microservices correctly
is the event driven approach
remember we talked about how difficult
it could be to add a new microservice to
the application due to the circular
logic issue
well the good news is that we can
overcome this problem by adopting the
event-driven architecture instead of the
request response one
to compare these two approaches we will
use an equivalent real-life example of a
passenger
ordering a taxi from a ride sharing app
in this example
the passenger is asking a question what
time does my taxi arrive
in the rest api world the driver would
respond
with a specific time say 8 45 pm
however if we change the question to is
my right ready
the driver would respond with the answer
no
as the answer is not the expected one
the passenger will have to continue
asking the same question until they
finally receive the expected answer
from a human perspective this situation
is quite repetitive and annoying
event-driven api interaction patterns
differ
from rest api in the event-driven world
the event would be initiated by the
driver
the passenger has to define an endpoint
that the driver can call in order to
send the notification
the passenger is notified as soon as the
piece of information is ready
this type of interaction is referred to
as
webhook and is the preferred style of
a synchronous api this kind of
interaction forms the basis of
event-driven architecture
have fundamentally changed the way
applications
are built these days rather than a
single
giant monolithic code base hosting all
of the business logic inside
microservices reflect the distributed
systems model
where a group of application components
works together to deliver the business
needs
by following the microservices best
practices discussed in this presentation
you should be able to build better
architected apps
that scale well