Thursday, October 13, 2016

GOTO 2015 • DDD & Microservices: At Last, Some Boundaries! • Eric Evans

n for the concept of domain driven design
that's DVD and today i'll be talking about a certain aspect or a few aspects
of domain driven design that are
I think applicable to micro services or perhaps from my perspective of the
reasons that i found microservices to be an exciting opportunity for people
trying to do domain-driven design that's really what I'm more interested in
so starting out
I want to just briefly a point out what are some things that got me interested
in micro services in first place
well I certainly was inspired by the the stories I heard about what was done in
netflix i think it's important at this point to recognize that microservices
come in many flavors so I don't think that the things that I think of as micro
servers are necessarily representative of everything everyone is doing
certainly what i say is based on my understanding what they did at Netflix
mostly and the creation of of truly isolated place for an autonomous team to
do development was the single thing i think i think was most important to me
because for as long as I can remember I've been
advocating for example that a team that's developing some complex piece of
logic should have their own isolated data store and not have to share some
huge database that it has some kind of mishmash of different people's ideas of
what the data should be and so forth
the free for all of that makes it very difficult to do sophisticated modeling
and and subtle designs that can solve intricate business problems so that was
one of the first things that I thought while we could really use this and I
started trying to get some people on projects that i was on to adopt that
just that this say let's just isolate a piece of business logic put it at the
end of a message queue and say it can't share data with anything else except
what center that Q and see what happens
and it was it was very interesting very successful experiment required going
back and saying i will see you still have a connection to the to the other
database don't you
so let's keep going it was funny how persistent those attitudes were one of
the things about microservices is that it seems to acknowledge the rough and
tumble of enterprise development in a way that most philosophies of software
development do not one thing that I am more than tired of his sort of
idealistic views of software development and software systems large software
systems
it just isn't like that there's so much going on and it's so rough and tumble is
the phrase that always comes to my mind
now if what you want to do is to address an interesting and intricate problem
with a subtle model those things are fragile those things are like snowflakes
and you have to
have a way of having those exist within an overall rough-and-tumble situation
and a lot of times when people start talking about doing sophisticated design
it's a few steps down the road you realize that part of the idea there is
that the entire world will be redesigned and everything will be very elegant and
tidy and that will never happen
so so if you value your design then you value ways of isolating those things
from from that outer world and you have to have a philosophy that fully
acknowledges the reality that i think that there is a kind of boldness to the
microservices philosophy that really appeals to me and I think that things
like cattle not pets and the simian army just really inspired me with their
boldness and and innovation
now these are mostly run time considerations you know you deploy
something and that's when you treat it as a you know livestock rather than pet
and you deploy things and that's when you knock them down with chaos monkeys
and so forth
so what's interesting is that this philosophy seems to have started from
that perspective of deployment and then change the way people actually do the
development and design work and that's a different you know that's a different
approach
I mean in the sense of where you start and where you end up then most of the
software philosophies that I was exposed to earlier in my career I think it's
very interesting
it's a break from the past and sometimes incremental changes don't work for
various reasons i'm one of them is that are a mindset when we see incremental
changes
we perceive them as being the same thing as before
people don't realize that some subtly different concept is different but when
you have something that's true radical break then things get really shaken up
and it's a chance for people to think differently
that doesn't mean that everything that the microservices people do is going to
work
I think far from it it's like any new thing is going to have a lot of miss
guided things going on in it but it's truly exciting new shake-up
so with this caveat that I think microservice it does seem to mean a lot
of different things to different people this is basically where I'm coming from
and and the things that I'm about to say are based on that perspective
now what is a service will if we just take sort of a very basic say that
service is something that can consume messages and produce messages and in in
there in between inside of that service it
anything could happen right it can have a lot of data or you could have very
little data you have a lot of logic very little logic
there's a service and so let's imagine that there are two services and these
two services actually use information produced by the other one through
messages
now the question that I ask is how do they understand the messages
how do i understand a message that's produced by another service as service
that is built by an autonomous team right a different autonomous team in
mind so this message is that they're sent thing to out
they're not really necessarily sending them specifically to me but the messages
are sending out or in some language so I'm just labeling the messages according
to the service that produced them so the message is coming from a are in the a
language and the message is coming from beer in the B language
how do they understand them obviously the software is written in such a way
that they can interpret these messages that they can interpret any of the ones
that they've chosen to consume now understanding messages requires some
kind of context
this isn't anything about specific the microservices this is just the way
language works
you can never understand the phrase that you here unless you know the context and
so when and this is something that with that I tried to make very explicit in
domain driven design is that when we're doing models that the the most central
thing about a model is often the language that you create that allows you
to express the problem and solution very crisply and to have that clarity of
language you have to make context clear and in practice in software that means
making an explicit boundary not the subtlety with which we interpret context
in normal conversation just immensely complex but simply drawing a line around
something and saying within this space
this is what this word means this is these are the rules here
so um I call that a bounded context
now we could say that a and B are each one of these bounded context within a
that establishes a boundary and within be that established the boundary and
inside of there they've each to find their language and we have established a
translation between the tube and in this case the way I this story seems to be
going we're going to say that a and B do actually actively collaborate with each
other that is the people the people developing a and B they collaborate with
each other
we're going to call this a partnership and that translator is a way of saying
messages from a can be transformed into the v language
and vice versa and language be can be transformed into a and they both care
about that translation now see comes along is another service and they are
consuming messages coming from a but this is not that kind of mutual
collaborative relationship that a and B have established see is consuming and
doing something with these messages and but a is not as interested in sea as
they are in be so this is a an asymmetrical relationship kind of
upstream and downstream relationship and so when I put these on to this diagram
and this lower diagram we call the context map because it shows all these
different context now they relate to put an arrow which says this is the
direction where the power is that is to say that the communications between a
and B follow the decisions that a makes rather sorry between a and C follow
decisions that a makes not decisions that seem aches so the arrow points
toward a now in a situation like this
she has to make a decision how am I going to deal with that the fact that I
don't control the kind of messages that I'm receiving in this case C has made
the decision that they will conform to a that is I will make my design
compatible with a so that the messages
the language of a will be a my language will be a lot like their language
I will make it so much like their language that it will be very easy for
me to consume their inputs the outputs
this output from a seems to be very useful and along comes the another
service and the also wants to consume the message is coming from a but they've
made a different decision they have said the things that we need to do within our
service are substantially different than apparently what the a people having my
it sufficiently different and complex that we need to control our own model we
need to change the language
so we're going to put a significant translation in place now there is a
significant translation between a and B but it's one that's managed between the
two and the two are coordinating their development but he is not
they simply are consuming the a messages as they come so we call this an
anti-corruption layer I'm going to build a little wall between me and you and it
will transform those incoming messages into a form that i will use and it's no
one else's business how this works
I think that all of these things happen and routinely whenever we have multiple
teams developing independently and integrating with each other
it's helpful to make it explicit have a picture of what's going on that people
can see it a high level
of course microservices the ideas you'll have many of them and so now along comes
e.e is going to actually provide some inputs that a will use but they're going
to do it in a daze language
this is somewhat common what it means is that first for internal organizational
reasons perhaps the a people are able to say we need you to send us messages in
this form
now this means that he is conforming to a that the direction of the arrows in a
context map
don't correspond to data flow direction they correspond to the direction of the
power and a seems to be in a very influential position so see conforms to
them while they consume but akin it but he also conforms and they are providing
a with information
all right he is also going to send this same data to d
now he is now consuming messages in the a language from a and from E but you'll
notice that there's really no need to change the context map the context map
is not a map of where the messages are going
it's the map of who has to understand whose language where the translation
points and basically what decision did they make about their relationship to
the other language now f
f is going to consume bees language and admit things in its own so c is going to
consume those and it has to decide
well see decided to conform to F but f is not conforming to be
now you might say are now see is conforming to F&A which would be a
problem if FNA are providing similar kinds of information right if you were
sending me a listing of movies and or if a is sending out a listing of movies and
f is sending out a listing of movies and I'm trying to conform to both ways of
listing movies
that'll be a problem but if one of them is sending the list of movies and the
other one is sending me some completely different information that's a credit
card statements
well that's no problem that i can conform to both
alright so one . as we you know deal with how are we going to do modeling
make it practical a practical tool
one of the things that people often miss i think is that models need to be clear
they don't need to be big one of the worst of kinds of models that I've seen
is the sort of the enterprise model or things that are moving in that direction
where every piece of information that someone might ever want to use it
somehow finds a home within this enormous schema or where they are
working out a way to compute almost anything within a given domain the most
valuable models that i have created and used in my career have been actually
quite modest in scope and this fits neatly within this idea that bounded
context we need to have very crisp definitions
hmm and for that we need a clear bounded context also
the most interesting models tend to make assertions that simplify the
interpretation of what's happening and assertions require boundaries because
anything I an assertion is simply making a statement and saying this is all this
is true this is always through and you can never
you can almost never make statements like that in general
so you need a boundary but with a bounded context you can make such
statements
so there are always multiple models that is a good thing and it's a thing that is
very sort of part of the air of microservices I think it seems extremely
natural in that kind of a paradigm now
as we go along in this back to the story of of our context map
well people don't always make good decisions in the f context they make a
few poor choices about how they represent the data about how they
compute things in general it's a it's a bit of a mess
and since c is conforming to F that mess is a immediately going to migrate into
see that is if I conform to a mess
then what does that make me so remember the the kind of design i'm talking about
is where clarity is the premium and f is lost the clarity and as a result she has
lost their clarity
that's one of the consequences of conforming there are good things about
can for me but this is one of the downsides
now II has made some poor choices as a consequence of he being a bit of a mess
now
the message is they're emitting which are supposed to be conforming to a no
longer really are
that is to say if I may
I'm receiving messages in a form which was supposed to be in that justice i had
dictated but it actually is not
this isn't a choice that that the the E people have made
it's just that they didn't pull it off they just don't quite have the for the
competence or they just messed up this one time
so now what's going to happen well in the ideal world the pressure from a and
D the to consumers would probably push them to get their act together and go
back to it
meeting well formed a messages in the ideal world but i have never worked in
the ideal world in the world where I work
right now there is a great risk that both a and D are about to become
corrupted by this that the model of a will start to have to accommodate a
little bit of E and the same goes for d and those gray circles are just going to
fill the screen there is another possibility but we'll get to that in a
minute
this picture right now is a fictional picture it
by that I mean that what's really happening up above is that he is not
conforming to a but the picture still says that they are so we're going to
need to change that picture
we want the context map to reflect what is really happening whether we like it
or not
now not all of a large system will be well designed
I think that anyone who cares about good design needs to drum this into their
mind like say it three times themselves in the mirror every morning because if
you don't do that you will you know you will end up without any good design
because you'll you over reach you keep trying to fix everything right making
you know about fixing nothing spreading your work too thin
so the real question is in this situation
yes i mean it it would be worth looking into getting each to fix things up but
recognizing when they're not going to do that
what are we going to do about these two relationships right now there's no real
clear way to write this thing on to the context map because it's just not a good
situation for the most part
the patterns in the context mapping technique are ways to describe
reasonably healthy relationships
one way would be for each of them to introduce an anti-corruption there for
the a people to say well maybe we can get e to fix things up some day at some
point but meanwhile we need to protect the integrity of our model and that
means that we will receive these sort of twisted AE messages and we will
translate them into nice clean a messages before they come in to us that
anti-corruption layer is essentially a translator that takes message of one
language and turns them into messages in another language and now we are back in
a situation where even though there is some you know there are several contexts
here now that are not well designed yet that doesn't inevitably lead to a
degeneration of all the design in all the context
so we needed level of reason of reality to prevent that
alright so that's um that's the first thing i wanted to get it crosses
what is it that made me think that microservices would be a good vehicle
for domain driven design and basically it comes down to this kind of you know
you give a real isolation to the work within these different teams within
these different contexts
you have a way of of managing that in most of the traditional techniques it's
much harder to make clear boundaries and enforce them
now one of the things that happens with any kind of you know
let's break things into smaller things approach is that you end up with a lot
of small things and it gets to be very hard to to see the big picture and it
gets hard to make coherent designs on the larger scale
one of the common things that that I see though
what people often do with microservices is what i've dubbed the interchange
context and so let's look at this for example this is before he went off the
rails
so we've got right now we have one two three four context that receive a type
messages
in addition to a itself so you have a lot of communication happening in this
one language this language is becoming the de facto interchange language that
is to say that more and more of these different services are speaking a now
that is actually pretty common that someone designed it may be though for
quite a specific reason and then it becomes used for that another way of
doing it though
if you if you were to anticipate such a interchange language might be to try to
devise one that was actually suit well suited to that
remember that a language was primarily probably intended for the logic that a
does the way they think about the problem for their purposes
Plus perhaps their collaboration with be a very specific collaboration but
actually ed see they never were too interested in that
if you had designed a more generic
kind of language for communicating with them
you probably would have chosen something different and this is an opportunity
that i think is not one that you'd want to do up front but when you see
something emerging like this where you suddenly see that this service this
context is becoming the fact that language for a large part of the
communication within a system you might say let's devise a new language that is
just for that purpose
so this would be another context this context does not correspond to a service
so it so context is the first one up here that actually has no physical form
at all it's just a sort of weight of of talking about things
it's got crisp definitions the cover range of things that these contexts like
to talk to each other about but it doesn't get into the kind of things they
need in order to actually solve their internal problems which probably a does
have some baggage of that kind as I say I don't like to anticipate these things
and do them before we start I like to kind of let the need for it
come upon us now one of the things when i am talking with people who are not
microservices fan but actually you know and I say oh I like the microservices
thing I think it's good for creating these boundaries and so forth and they
say well a lot of the things that you're saying you like are just logical
boundaries i mean we don't really need all that machinery for this
we don't need separate deployment you know why would we do all this separate
deployments not sure if you need to scale
you know scale some services at very different levels of scaling and you need
that kind of fail over and you need all those things that's one way to do it
but the things that I've been talking about are not mostly about that they're
not mostly about that runtime side they're mostly about the effects that
that philosophy has on the development phase right and I'm saying I think the
effects that that has on development phase seem to be quite good and so I I
think they're undeniably right that there are in principle other ways to
create logical boundaries and my response is simply that we've been
trying to do that for decades now
ever since I've been in this field and I think before then
people have tried to establish those kind of logical boundaries in various
subtle ways and I think it's just too subtle it's too
it doesn't survive the rough-and-tumble there's always it's always too tempting
and too easy to pierce through the boundary and grab the piece of
information you need from the database or whatever and microservices by putting
all that machinery there makes it a actually unnatural to do that it makes
it more natural to do the thing that maintains the isolation
sometimes you know you need a wall you
you have perhaps offense between your house and the next house you could just
sort of draw a dotted line there
you know on the grass but there's something about a wall so i think that
this is the reason and I just I just I don't really have to understand it to
have just observed that we've been trying and trying and trying to do this
for a long long time but this when i have introduced to this approach in a
project that was trying to isolate things in more logical ways the physical
isolation and the visibility it gave and other things
seems to have done the trick and pushed it over into truly decoupling pieces of
the system so you may be driven mostly by the runtime advantages you may need
to scale parts of your system
the client that I did this with the first time really wasn't scaling that
big
they rightly pointed out that they could handle the problem that they had without
all that stuff but we did it and it produced to the coupling that allowed us
to do the design better course if you need to do the scaling and the other
advantages then that makes it much easier choice
alright so basically my points are these that when we want to do subtle design
and it doesn't have to just be domain-driven design but any kind of of
intricate logic we need clarity a degree of precision that demands isolation
so we need some kind of concrete boundary and i'll have to say that the
best ones I've seen
we're the ones that been cooked up in the microservices world
I'm sure it's not the only way to do it it's just proven to be effective in my
personal experience and it's here
you know it's real when you get a whole lot of these services you're going to
see some of the same problems crop up
really you know you describe service and winced when people start scaling the
micro service down to say a nano service where people start talking about a
serious that might have 20 lines of code in it or something and I start thinking
boy that sounds like an object and
because you know and especially the the way objects were in the old days like
small talk objects are little things that can send messages to each other and
so on and and I i think that there are you know distinctions of course I'm not
saying they are objects but there are a lot like them and some of the same
problems arise will arise anyway and so you know this is not a panacea
it's not a solution to all the problems but i think that some of those problems
then can be addressed with tools like context mapping which was specifically
to address this kind of problem to say you can understand a certain collection
of elements that have been crafted to solve set of problems and then another
set of elements which have been crafted to set to solve a different set of
problems but you can't understand all of it all at the same time
and furthermore those different elements have been conceived using different
concepts different language
so we need boundaries between them and then we need a way of seeing how they
relate to each other so the bounty context and context maps helps to make
that explicit even you know both in the situation where a service defines the
context boundary but also in the case where the communication of several
services where the message is going between them
defines a context not the interior of the services but the messages between
that space in between is another context it helps us to visualize that and reason
about it so i think that the modest use of interchange languages would be one
way of helping to organize a coherent set of services that solves a somewhat
bigger problem and I think people actually do this you know but without
any explicit tools to explicit mental tools I mean to talk about it
just say one more time before I wrap up that not all of a large system will be
well designed and you can even and that I think is you know a natural part of
the microservices philosophy
it's one that we have to carry over even to the point of saying even though
microservices properties won't be perfectly exhibited within a large
system there will be fragile parts and there will be parts that don't scale
right and so forth
parts that get tangled with other parts in such ways that make it very difficult
to do the things you do that you talked about doing three placing and so on but
that's all right
you know if it is not meant to provide create a perfect system went to get
things moving and and freshen things up so
and on that i'll close and and hopefully leave some time for Question
yeah we do so thanks for the talk
and one of the questions from the onto this is that design all bonded context
this ABC and so on
would they be separated microservices and put their be separately deployed so
the question was this
these contexts the ABC and so on would they be micro services that were
separately deployed and the answer is yes that's what I'm that's what I'm
suggesting that you know would say an old-fashioned approach the we would try
to define these contexts in other ways maybe they would be a certain set of
modules and a certain set of tables they were associated with those modules and
you'd have maybe a document describing the more some kind of labeling within
the comments and and all these ways of trying to say these are the boundaries
of this context what I'm saying about microservices is that one thing it seems
to do is it says this service is a context
one team owns it it's isolated it doesn't share data
I mean it doesn't shares data but only through the interface it doesn't share a
database and so on and so the boundaries of this context are very well defined
ok then there was questioned the wall
you called a see what is what does it mean in the context map
Oh anti-corruption layer
yes 8a c is for anti corruption and I guess I I apologize for not defining
that when it's become such a common little abbreviation that we use that I
idea
forgot to end it the point of the name is that if I am consuming information
say a message
that's coming from outside that can corrupt my fragile high precision design
you know and so I have this you know if you car engine is very high precision
machine that has to operate in a fairly dirty and uncontrolled environment and
what does it have it has filters right the air that goes into the engine goes
through an air filter
there's a oil filter that constantly is cleaning things so they don't get into
the engine and so on so they know that that kind of high-precision thing unless
you're going to operate in a clean room somewhere in which case it doesn't need
all that well that is a massive anti-corruption layer that's used for
those kind of things actually
so to have to have a really high precision solution you need that kind of
protection
the other and not all problems are so high precision right that the you know
the car's engine has all that kind of filtration and stuff but you know the
windshield wipers don't have that they just what i find the windows and
eventually they wear out and we replace them
and you know they're low precision parts to a car and their high precision parts
and the high precision parts need to be treated differently they need that
isolation and so if you're consuming data from outside that context
you can't assume that it's meets the requirements that you would think it
would have so you check those things and Plus you transform it into the same
terminology the same structure that you would be expecting data that's moving
around in in on the inside and then once these are on the inside you can make
lots of assumptions and make assertions about the nature of the data that you're
working with
ok and there is another similar question so a BB om
what's that wow yeah so BB om short for a big ball of mud and i decided i
actually did consciously decide to not use that term in the talk and i forgot
to take the BBM off of the slides but it is a wonderful
you know you should just google for big ball of mud and find the original big
ball of mud paper which is from the nineties and it described systems that
have just grown into big messes of tangled but the great thing about that
paper is that it describes these in a kind of admiring way like how they
observe that most big systems are like that and that somehow it works in there
is something about that anyway so it's very clever paper so i was just saying
that we were getting some big balls mode that they probably weren't very big
ok so more about the the architecture and one of the questions is can or
should there be a dedicated service
whose purposes to only be an interchange context provider
I guess that was the I that you had in your chart should there be a service
dedicated to being the interchange context provider
I think
that my answer would be no I said without a lot of Khan a lot of
confidence because yes you could imagine everything getting but i think my answer
would be no because the point here is to keep the decentralization of the
microservices architecture don't create some bottle and consult but on the other
hand give us a way to exchange messages without quite so much translation
perhaps and we can do that without having some kind of special service that
i'm not sure what it would do you know unless you had a database that stored
things in that form but basically ice
I think my answer is no but if someone comes up with some solutions you know
not all that dogmatic about these things
ok so another one that is more about the organization
so would you recommend the one on one to one relationship between teams and bone
contexts
would I have a one-to-one relation between teams inbound context i would
have an one to end that is I want a bounded context to have a clear owner so
I would want to say if this thing is a context a service then there's a team
that owns it but a team might work on multiple services so as long as you
don't have the problematic one is when you have two teams that work on the same
thing and you see that in in places where they carry the concept of shared
common ownership too far too far in my view without any context boundary
separation where anyone can change anything within the system so people
lightly touch a part of the system that they don't understand very well and you
have the tragedy of the Commons and everything just kind of degenerates
so the context should have one owner but a team might conceivably own more than
one
ok and air me and does that mean that only the team is supposed to change the
code of those bonds of context that is what I need yes
ok so and this is so this powerful separation that you're talking about
isn't that also a problem because if things don't turn out as expected so if
one of the team's doesn't really deliver
it's going to be hard to is to find some way of going into production and then
you might have even the little company feel so i think it
this is a problem this idea that if one team fails to deliver that it will lead
to a kind of bigger failure
that is a problem which you would face under any circumstances
in fact you know the micro services is perhaps a little more resilient to such
things than more monolithic approach but if you look at some of the diagrams
another nice thing about the diagrams i think is it can give you a hint about
the consequences like if if if she doesn't come through then probably it
won't affect a very much but if a lookout terrible it would be of a
screwed-up you know that so you know that the consequences of mistakes and
they are dire throughout the organization so i don't i would say that
might help us nowhere to worry
and if I didn't trust a and I were see I'd be thinking maybe I should you know
another thing i'll throw in here
one thing I've seen is that people sometimes value the dry principle to
highly that is the don't repeat or so that don't duplicate stuff too highly
so let's suppose that what a really wants from either what C is really
wanting from a is some particular capability that really isn't that hard
I would rather see see duplicated of course the ideal might be that this
thing would be broken out and not be part of a or C but i remember we don't
have the ideal but it in great if if you've created a dependency on a whole
other team and their success
just to have this function that they've already built
well maybe it's better to do some duplicating ok so i guess the final
question can we use the logical boundaries here to create multiple
microservices in a top-down way and I guess closely associated with that
question doesn't make any sense to create a model with first and then go
for micro services and what was the first part they're so air whether you
could use these logical boundaries to create multiple microservices top down
ah so would you sort of plan out in and then
yeah I am NOT against a little bit of upfront planning a kind of a sketch and
then let's go do something kind of thing which i think is very different from
meticulously planning everything out in advance so i wouldn't i think such a
thing you know you
I think you actually are bound to do that a little bit as you say well what
are our first two or three services going to be and we're going to have a
couple teams working on them
ok let's go work on that now so that is a little bit
top down but not from very high up right and then the other part doesn't make
sense to make the monolith first
you know I i actually don't think so but people say that that have experienced
and and good results and so although it it goes a little bit against my sense
that I think actually that I would
at this point i would start with something pretty broken up
chilly but I'm not gonna i don't i don't think i have a very strong opinion about
that one
ok thanks . again thanks for financing the questions in total
thank you