Responsible Microservices
Responsible Microservices
m
pl
im
en
ts
of
Responsible
Microservices
Where Microservices
Deliver Value
Nathaniel Schutta
REPORT
Responsible Microservices
Where Microservices Deliver Value
Nathaniel Schutta
978-1-492-08526-3
[LSI]
Table of Contents
4. Independent Scalability. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
The Monolith Forced Decisions Early—with Incomplete
Information 25
Not All Traffic Is Predictable 26
Scale Up Where It Is Needed 27
Monitoring for Fun and Profit 28
All Services Are Equal (But Some Services Are More Equal
than Others) 31
Modernize Your Architecture to Use Modern Infrastructure 32
iii
5. Failure Isolation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
No Service Is an Island 33
Architectural Reviews 35
Failures Find a Way 36
Engineering Discipline 40
6. Indirection Layers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Abstract Away External Dependencies 41
Managing Your Services 43
The Importance of Architecture 44
9. Migrating to Microservices. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Modular Monoliths, Macro Services, Oh My! 57
Decomposing the Monolith 59
Next Steps 61
iv | Table of Contents
CHAPTER 1
The Microservice Revolution
1 For more on this concept, see The Mythical Man Month by Frederick P. Brooks Jr.
(Addison-Wesley).
1
How Did We Get Here?
Odds are you’ve noticed a major shift in how your organization
approaches infrastructure. Servers were once homegrown—a
bespoke artisanal approach. And while you may enjoy the idiosyn‐
cratic when it comes to your morning coffee or your favorite food
truck, unnecessary variables in your infrastructure lead to sleepless
nights. During this “Paleolithic” era of software, servers were a very
expensive resource, forcing developers to deploy as many apps to
the same hardware as possible. Doing so may have placated the
accountants, but it introduced its own set of problems.
With shared resources, one application’s bug could impact every
application on a given box. Upgrades to common libraries were con‐
strained by the slowest-moving system in the environment, making
currency projects a frustrating series of freezes and testing. Organi‐
zations often kicked the can down the street rather than deal with
vital (but not flashy) currency projects. Afraid of breaking anything,
many companies poured proverbial concrete over their infrastruc‐
ture, allowing fear to lead them down a dark path. Who knew there
was such a thing as #YodaOps?
Fear is the path to the dark side. Fear leads to anger. Anger leads to
hate. Hate leads to suffering.
—Yoda, Star Wars Episode I: The Phantom Menace
2 See Thinking Architecturally, another report from O’Reilly, for more on this concept.
What’s in a Name?
If you’ve already debated tabs versus spaces, consider touching off a
discussion around the definition of a microservice. Consider
removing sharp objects—it may devolve rapidly. Microservices
really are in the eye of the beholder!
What Is a Microservice? | 5
constantly changing, the exact same team might struggle with more
than five!
Rather than debate designations, think in terms of characteristics.
Microservices are suites of small, focused services that embody the
Unix ethos of small, focused tools that do one thing and do it well.4
Microservices should be independently deployable, independently
scalable, and free to evolve at different rates. Developers are free to
choose the best technology to build services around business capa‐
bilities. In a nutshell, microservices are an example of what I refer to
as the zeroth law of computer science—high cohesion, low coupling—
applied to services.
9
Figure 2-1. For your consideration…the Widget.io Monolith!
Odds are, the cart module probably hasn’t changed much and the
inventory system is really stable.1 Meanwhile, your product owner
constantly wants changes to the recommendation engine, and no
one has ever said “Our search is too good.” In the monolith, every‐
thing has to move at the same rate, which is part of the rationale
behind quarterly release cycles.
Today we have options. Splitting those two modules—recommenda‐
tion engine and search—into microservices would allow the respec‐
tive pieces to iterate at a faster pace. This approach will help you
quickly deliver business value. Separating the things that change
more frequently results in something like Figure 2-2.
1 Let’s be honest, it’s probably tied to some legacy warehouse system you have no power
to change.
2 From Memoirs of the Life, Writings, and Discoveries of Sir Isaac Newton by Sir David
Brewster (1855): “I do not know what I may appear to the world, but to myself I seem
to have been only like a boy playing on the seashore, and diverting myself in now and
then finding a smoother pebble or a prettier shell than ordinary, whilst the great ocean
of truth lay all undiscovered before me.”
For a variety of reasons, you often find parts of your application that
need their own commit-to-production flow. Let’s consider this
dynamic and how microservices can help. Independent life cycles are
a larger concept that is arguably a superset of multiple rates of
change, allowing you to be nimbler in today’s disrupted marketplace.
Always Be Changing
Monoliths are big ships and they don’t turn on a dime. While that
might have been workable a long time ago in a galaxy far, far away,
today you must be able to respond to an increasingly dynamic envi‐
ronment. Speed matters, and your business partners may not be able
to wait for a quarterly release window. Standalone microservices can
have their own life cycle with their own repository and a separate
deployment pipeline containing the appropriate tests and code qual‐
ity scans allowing you to capitalize on new opportunities.
The semiannual release cycle doesn’t cut it anymore. A monolithic
approach usually hinders our ability to deliver quickly, run A/B
tests, and learn from users. Chances are, you are being asked to
innovate in days or weeks, certainly not months or years. Disruption
impacts every business today, and your industry is not immune.
Returning to the Widget.io example, what happens if your business
partners identify a new opportunity? Can you get that functionality
into production sooner rather than later? You could tell them to just
wait until the next release, but the business opportunity might van‐
ish. Instead, consider the approach described in Figure 3-1. Giving
15
the new functionality its own life cycle frees it from the schedule tyr‐
anny of the slowest-moving part of the application.
Documenting Services
Documentation, much like the cobbler’s children, often gets neglec‐
ted on software projects. Developers typically prioritize features
and functionality.1 Word processors don’t lend themselves to a
deployment pipeline, and updating documentation can seem like
yet another dollop of busywork. Spring REST Docs takes your
handwritten Asciidoctor (or Markdown) text and combines it with
autogenerated snippets from Spring MVC Test, WebTestClient, or
REST Assured.
Multiple Owners
While not a technical issue, if your system has multiple independ‐
ent, autonomous business owners, then it has two distinct sources
of change. Unfortunately, this situation often results in conflicts.
With microservices, you can achieve independent life cycles and
please these different constituencies.
Similarly, if an application is owned by multiple teams, the resulting
coordination cost for them working on a single system can be high.
Instead, define APIs for them. From there, each team can build an
independent microservice using Spring Cloud Contract or Pact for
consumer-driven contracts testing.
Hypothesis-Driven Development
Independent life cycles make your life better. They also allow you to
make more informed decisions about how your software should
evolve. Throughout my career, I have had countless debates with fel‐
low software engineers and customers about possible solutions for
various scenarios. And while there were always strong opinions,
data was hard to come by. We had to make a decision based on what
little we knew and hope for the best.
Of course, even if we were wrong, lengthy deployment cycles meant
it would be months before we could alter course. These constraints
forced us to be conservative. We couldn’t afford to try something
unconventional, lest it alienate our users.
Prediction is very difficult, especially if it’s about the future.
—Niels Bohr (attributed)
Hypothesis-Driven Development | 19
Taking its cue from a traditional user story, you can formulate some‐
thing like this:
For example:
And, you can often turn that structure into a fitness function that
you regularly execute against your code.
When a given service has its own commit-to-production flow, you
can run multiple experiments reacting to actual results instead of
spending countless hours arguing about the future. Today, compa‐
nies like Google and Amazon run multiple experiments daily (some‐
times hourly!). They constantly A/B test. The result: hard data about
the impact of a given design on key metrics. What customer doesn’t
want constantly improving products aligned ever more closely with
their needs? More practically, what software organization doesn’t
want to deliver this kind of service? This is another reason why
microservices are so popular.
While it may be easy enough to want independent life cycles, it can
be daunting to actually achieve it. Regardless of why you are using
microservices, you will need a heavy dose of automation in your
build process. You need deployment pipelines.
Deployment Pipelines
Modern distributed architectures, along with cloud environments,
give you a powerful toolkit to build applications that quickly deliver
business value. You can no longer afford a plodding release cycle
with nebulous review boards and heavyweight gates slowing devel‐
opment to a crawl. But how can you ensure releases don’t bring
down production? You need to move fast, but you cannot afford to
break things—you need deployment pipelines. Leveraging continuous
3 There is some ambiguity about the definition of the D in CD. Arguably the most com‐
mon meaning is as described here. Continuous deployment is one step beyond contin‐
uous delivery where changes that successfully pass all the gates of the deployment
pipelines are automatically moved to production. Continuous deployment requires a
significant investment in testing to ensure changes do not cause havoc in production,
and typically involves feature flags and other advanced techniques.
Deployment Pipelines | 21
Deployment pipelines give you a well-worn path to production. You
can’t become an expert at a given task when you only do it once or
twice; expertise grows with repetition. Deploy often, and you
develop a kind of digital muscle memory. If you only randomly
expose your code to unit tests or linting, you can’t expect much
improvement. But if you subject your code to the same procedures
on each and every commit, you develop a process you can trust.
To support these more dynamic environments, companies are
increasingly turning to automation to ensure a consistent, repeatable
delivery process. While artisanal coffee may make your morning
better, an irreplicable build process isn’t anyone’s definition of a
good way to start your day. It turns out that people aren’t very good
at doing the same things over and over again (see golf). To ensure
that the code you deploy to production meets your expectations, it
should pass through a rigorous process. Tools like Concourse, Azure
DevOps, and Jenkins help you create robust pipelines. You can craft
the proper gates, and gain confidence that your code can pass the
proverbial gauntlet.
These pipelines were once bespoke one-off endeavors. Today you
can leverage projects like Spring Cloud Pipelines or dotnet-pipelines
as a starting point. Following an opinionated build/test/stage/prod
flow, you can be up and running in your own environment quickly.
And you can be sure that your code does what you say it does,
thanks to a shortened “idea to production” cycle.
4 See Vincent Martí’s 2015 post, “Move Fast and Fix Things,” on the GitHub blog.
Monoliths often force you to make decisions early, when you know
the least about the forces acting on your system. Your infrastructure
engineers probably asked you how much capacity your application
needs, forcing a “Take the worst case and double it” mentality, lead‐
ing to poor resource utilization. Instead of wild guesses, a microser‐
vice approach allows you to more efficiently allocate compute. No
longer are you forced into a one-size-fits-none approach; each ser‐
vice can scale independently.
25
case—strange things happen in traditional enterprise IT.1 But I do
know that these kinds of delays incent a raft of undesirable behavior.
Sadly, this experience is familiar to most IT professionals. Extended
lead times force you to make capacity decisions far too early. In fact,
the very start of a new initiative is when you know the least about
what your systems would actually look like under stress. So you’d
make an educated guess, based loosely on the worst-case scenario.
Then, you’d double it, and add some buffer. (Plus a little more just in
case.) In other words, you would just shrug your shoulders as in
Figure 4-1.
Figure 4-1. How much capacity would you say you need?
1 I theorize that a team wrote a database as part of the request, but I could be wrong.
Figure 4-2. Microservices allow you to scale up the parts of your appli‐
cation that need it
2 For more on this topic, see chapter 6 of Site Reliability Engineering, “Monitoring Dis‐
tributed Systems.”
3 If you don’t know the scalability characteristics of your app, monitoring is a data-driven
way to determine those heuristics.
Last, but not least, monitoring is not just for production. When you
monitor staging, as well as lower regions, it validates your monitors.
Just as you test your code, you should also ensure your monitors are
doing what you expect them to do. Early monitoring not only allows
your team to gain much needed familiarity with your toolset, it is
also essential for performance and stress testing.4
All Services Are Equal (But Some Services Are More Equal than Others) | 31
important than the product recommendation service. This fact fur‐
ther reinforces our decision to refactor the Order Processing Ser‐
vice. Apply some due diligence to your services. Which of them
could be down for a few hours (or days) with minimal impact?
Which ones would the CEO know about instantly in the event of an
outage?
No Service Is an Island
Digital products don’t live alone. Every piece of tech you use today
interacts with something else. The same is true for the custom soft‐
ware you write. Each bit of code works as a part of a larger whole, it’s
just one piece of a system that executes a business process. The
name isn’t a coincidence: microservice implies interdependence with
other services.
Monoliths have plenty of dependencies, too. It’s common for mono‐
liths to integrate with an aging third-party application that you don’t
control. Often you are forced to wire these two systems together
with baling twine and duct tape. These engineers weren’t masochis‐
tic. They did the integration for good business reasons, most likely
to provide more complete information or a better user experience.
33
These integrations are a fact of life in software development. You
should expect to have connections between services that were never
designed to work together. You should also expect that external
services are unlikely to meet your service level objectives.
None of these are new—this list dates back many years!—yet many
of these mistakes continue to fester today. While you could debate
which is the most pernicious, it is clear that not everyone has
learned from the past.1
1 Speaking of learning from the past, read (or reread) “A Note on Distributed Comput‐
ing” by Jim Waldo, Geoff Wyant, Ann Wollrath, and Sam Kendall at Sun Microsystems
Laboratories, Inc.
Architectural Reviews
Odds are, you have a pretty good idea of what aspects of your sys‐
tem will benefit from failure isolation. But don’t assume you know
where all the dragons live. Take the time to perform an architectural
review. Gather all your subject-matter experts together—developers,
architects, and site reliability engineers. You don’t need any formal
architectural artifacts. Draw up the architecture (a whiteboard
works really well). Make sure to ask and answer questions like:
Architectural Reviews | 35
The Unbearable Lightness of Dates
Many years ago, I helped build an application for the team that
managed all our shared data—office codes, regions, states, that kind
of thing. A few months after turning the project over to the data
team, my director asked if I could help them with a build break. I
was happy to pitch in but pointed out they should review the last
change they made, only to discover they hadn’t updated the code‐
base in a few days. Interestingly, that morning a test broke. After
investigating, I discovered one of the tests I wrote was bound to fail
every seven years. I don’t honestly remember if I fixed the test or
simply noted it would fail again but it was a reminder of the odd
behavior calendars sometimes elicit.
I often reflect on this episode as a reminder of how difficult it can
be to imagine all the possible failure points in distributed architec‐
tures. It isn’t easy. Even trivial mistakes can have far-reaching unin‐
tended consequences. We owe it to our customers to explore the
“the road less traveled by.”2
All of this information will give you vital intelligence about where
your application might benefit from failure isolation. Refactor away!
3 Don’t neglect the other patterns Nygard identifies in his book, such as bulkhead, shed
load, and governor.
Chaos Engineering
Architectural reviews will help you find many soft spots in your sys‐
tem, but they won’t identify every instance where you could benefit
from failure isolation. Developers tend to be very good at identify‐
ing the “happy path” of an application. The “happy path” is the flow
a user should experience when everything is working as expected.
It’s far more challenging to anticipate all the ways your system can
go off the rails.
This is exponentially more difficult with distributed applications. A
number of services interacting in unpredictable ways leads to
unique, often chaotic, environments. How do you ensure a missed
failure case doesn’t spiral into a major system outage? Chaos engi‐
neering to the rescue!
The discipline of chaos engineering attempts to solve the inherent
difficulty in producing reliable distributed systems.4 After defining a
steady state (aka normal behavior), chaos engineering injects vari‐
ous issues that real-world systems encounter. Crash an application
instance. Simulate a network failure. Drop an availability zone.5 Fail‐
over from one cloud provider to another in production. How does
your application handle these situations?
Odds are, at least at first, chaos engineering will highlight some
weaknesses with your services. Once again, this result is a feature,
4 For more on this topic, check out Casey Rosenthal and Nora Jones’s book, Chaos Engi‐
neering (O’Reilly), “The Principles of Chaos Engineering,” and Adrian Cockcroft’s
dicussion of chaos architecture. You can also watch presentations from SpringOne Plat‐
form 2019 and QCon New York 2017.
5 Availability zones protect applications from datacenter failures by providing unique
physical locations within a given region. Redundancy is the name of the game, with
independent power, networking, and more.
Engineering Discipline
Microservices are a complex architectural option. But they are the
right one for certain scenarios, like when you need to isolate failure
in certain components. There are ways to reduce the complexity in
how you adopt microservices. Architectural reviews, combined with
some chaos engineering, will identify vulnerable areas of your cur‐
rent application. Think through how to respond to the inevitable
failures. Incorporate circuit breakers where they make sense.
Reliable services aren’t a guaranteed outcome of microservices—that
requires engineering discipline. Armed with the proper tools and
the right approach, your services won’t have you questioning your
chosen career! In Chapter 6, you will explore a specialization of fail‐
ure isolation, indirection layers.
In computer science, there are three answers that work for every
question you’ve ever been asked: “42,” “It depends,” and “Another
layer of indirection.” Microservices do not live alone; they work in
concert to deliver business value. Your services are constantly work‐
ing with a veritable cornucopia of other services, all of which are
changing and evolving at their own rate (see Chapter 2). How do
you protect your services?
This principle is similar to failure isolation (see Chapter 5), but with
a twist. Instead of guarding against the inevitable failures of our
services, we seek to protect them. “From what?” you ask. From
external dependencies that change frequently or are complex to use.
This pattern is common in software. Often, this is a vendor depend‐
ency, where one service provider is swapped for another. It could be
something large (like an ERP system), or something relatively sim‐
ple (like a mapping service).
41
Today, your applications and the systems they often rely on are
increasingly complex. When you need to simplify these interactions,
microservices can be an appropriate architectural choice.
A microservices architecture offers you a solution. Rather than
directly calling these dependencies, you can instead place an
abstraction layer (that you control) in between the core app and the
dependency. Arguably, this principle is a specialization of failure iso‐
lation (Chapter 5), but here we are protecting against a different
kind of failure.
Third-party systems are designed to solve a large set of problems,
many of which may not be relevant to your application. Instead of
forcing your service to understand the nuance of a complex interac‐
tion, you can build a microservice that exposes a simplified inter‐
face. That’s the essence of the facade pattern.
This approach is nothing new. In fact, it is one of the 23 original
Gang of Four patterns found in the classic book Design Patterns: Ele‐
ments of Reusable Object-Oriented Software by Gamma et al.
(Addison-Wesley). Facades don’t just facilitate evolutionary archi‐
tecture.1 They can also be used to simplify a complex service.
That isn’t all a microservice facade can do for you, though. Imagine
a third-party service that requires a bit of context that doesn’t
change from invocation to invocation. Perhaps a payment gateway
uses your corporate headquarters’ location for a calculation, or a
vendor requires a token authorizing your use of their API. Rather
than have each and every consumer incorporate that bit of business
information, your facade microservice can inject the context into
the third-party call. Not only does this approach simplify calling the
service, but it also makes it far easier to update in the future.
But that’s not all! A facade can perform additional functionality
before or after making the underlying request. In Chapter 2, you
read about the data-driven strangler approach. While obviously use‐
ful as part of a larger refactoring, a facade gives you a perfect place
to inject needed behavior into your call stack. Want to log the results
of the underlying invocation? Or maybe you need to create an audit
trail for every call to the third-party system. In either case, your
facade microservice makes such interactions trivial.
1 For more on this topic, see Building Evolutionary Architectures by Ford et al.
47
All was not puppies and rainbows during this era of software devel‐
opment, though. Things are never that simple—trade-offs are
unavoidable. Language standardization often exacerbated currency
issues. For example, shared servers lead to months-long slogs to
move from version N-2 to version N-1.1 In the amount of time it
took to complete an upgrade, a major new version of the technology
was often released. Eighteen months of freezes, testing, change-
review boards, and frustration was not the winning recipe for out‐
standing relationships with your business team.
Bespoke infrastructure often forced the lowest common denomina‐
tor for library and language versioning as well. Even if a team
wanted to move to the latest and greatest version of its preferred
tech stack, it may have been limited by the “slowest-moving” herit‐
age application in the house. How often have you heard a variation
of, “We can’t upgrade to X until the Wombat application is ready for
it?” Unless there was a burning platform moment (looking at you,
Windows XP), most product owners prioritize shiny new features
over paying down technical debt.
All that said, very few organizations were ever truly homogeneous.
Mergers and acquisitions happen, inevitably bringing new technolo‐
gies to the business. Some far-flung requirement would lead to the
introduction of a new database or language. But, as a rule, organiza‐
tions wanted to limit the technology solutions they supported.
Today, you have options; you aren’t beholden to a technology choice
made by someone five levels above you in the organizational chart.
It is tempting to reach for a new toy after reading about a new data‐
base or sitting through a webinar on an evolving language. But it is a
much more nuanced decision. Can you hire (or train) enough devel‐
opers with that particular skill set? Before you add complexity to
your environment, be sure you have compelling reasons to do so.
Cloud computing opened up a new universe of options and flexibil‐
ity. Elastic infrastructure combined with microservices architectures
enabled you to break free from the tyranny of a singular technology
stack. No longer are you required to pound a square peg into a
round hole. You can simply pick up a round peg! If a different data‐
base simplifies a solution, or if using an alternative language greatly
reduces the codebase for a service, you are free to choose the right
technology to fit the problem. The promise of polyglot program‐
ming is finally realized!2
However, there is a massive downside to a polyglot approach. To
(once again) paraphrase the mathematician in Jurassic Park: Just
because you can doesn’t mean you should. In today’s world, your
business is evolving at an ever-increasing pace. To keep up, you need
to ship high-quality code very quickly. Developers should be free to
choose the right tools for the job. So how do you empower your
teams responsibly?
Paved Roads
Every developer has their favorite languages, frameworks, and tools.
Products will have their own deployment pipelines, monitoring
suites, and preferred metrics. Without some guardrails, you will
quickly discover there are an awful lot of ways to “do that one thing,”
depending on who you ask. How do you develop any amount of
consistency if nothing is the same?
2 For more on this, see Neal Ford’s “Polyglot Programming” post from 2006.
Paved Roads | 49
Technical sprawl is only one consequence of a polyglot environ‐
ment, though. Consider the challenges in building a development
team that uses Go, Haskell, Java, .NET, Ruby, Python, and JavaScript.
Developers can always learn a new language, but it takes time to
start thinking in a given technology. The cognitive overhead of
maintaining disparate stacks can be worse than standardizing on a
one-size-fits-all model.
And don’t underestimate the inherent challenges of maintaining a
polyglot environment. For example, think about how much effort it
takes to stay current on one stack. Now multiply that toil by four or
five, and remember you’ve signed your development team up for a
long-term support agreement on each and every one of those frame‐
works. Don’t forget the ecosystem each stack requires—how much
will it cost to support the various logging, monitoring, and deploy‐
ment approaches as well?
Too much choice can be just as painful.3 Teams will spend hours
(more likely days) “debating” which one to use. Don’t be afraid to
establish some guardrails or guide posts. For example, you may
decide to standardize on the Java virtual machine (JVM), or to pro‐
vide well-worn paths to production on a limited set of tech stacks.
Teams may be allowed to venture off that path, but they take on the
responsibility (and the support burden) of that decision—you build
it, you run it.
With great power comes great responsibility.
—Uncle Ben, Spider-Man
3 Side note for all the parents out there: it’s much easier to give kids the choice between
two or three things rather than a limitless universe of options.
What’s culture got to do with anything? Well, you ignore the impact
of the transition to microservices on your organization’s culture at
your own peril. While it is tempting to dismiss the “softer” aspects
of a new technique, to truly succeed requires more than just writing
a strategy statement and adding a three-day class to your educa‐
tional offerings. You must consider the larger universe that your
technology choice lives within.
53
It is difficult to get a man to understand something when his salary
depends upon his not understanding it.1
—Upton Sinclair
1 Sinclair, “I, Candidate for Governor, and How I Got Licked,” Oakland Tribune, Decem‐
ber 1934.
2 Thompson, “The Curse of Culture”, Stratechery, May 24, 2016.
Microservices are great! If you need them, that is. The road to
microservices is paved with good intentions, but more than a few
teams are jumping on the bandwagon without analyzing their needs
first. Microservices are powerful, and they should absolutely be in
your toolbox. Just make sure you consider the trade-offs. There’s no
substitute for understanding the business drivers of your applica‐
tions; this is essential to determining the proper architectural
approach. And it turns out, they aren’t the only approach you can
leverage.
1 “Distributed Big Balls of Mud,” Coding the Architecture (blog), July 6, 2014.
57
Obviously, a distributed big ball of mud is the worst of both
worlds—all of the accidental complexity, none of the benefits of a
truly distributed system. Many have found moving to a modular
monolith first facilitates finding bounded contexts within your
application. It is possible to break a monolith into modules that give
you some of the benefits of highly distributed systems. From this
new normal, the microservices should be more evident and you can
continue your refactoring, stopping when you’ve reached the proper
return on your investment. Your architectural choices span modu‐
larity and distributability, as you can see in Figure 9-1.
2 Some organizations’ environments are so dynamic, they don’t have an exact count of
how many services are running at any given moment.
Of course, you aren’t starting with a blank slate, you have existing
applications. How do you decompose the monolith?
3 Newman, “How Big Should Microservices Be?” (video), uploaded May 3, 2020.
Once you have some candidate boundaries, you can test them! Are
there any “overloaded contexts”—that is, places where the context
does too many things? A multitude of if statements indicates you
probably have two or more domains. Is your context autonomous?
Can it make decisions on its own, or does it need to reach out to a
dozen other modules? It may seem a bit fuzzy, but don’t forget to do
a sanity check. Do these boundaries feel right?
There is a fair amount of art involved when you decompose a mono‐
lith—there is no magic formula. Hopefully, these tips will help and
give you a place to start your journey. Refactoring takes time, so be
patient; your portfolio wasn’t built in a day, and you won’t move
everything to the cloud in a week. Good luck!
Next Steps | 61
About the Author
Nathaniel T. Schutta is a software architect focused on cloud com‐
puting and building usable applications. A proponent of polyglot
programming, Nate has written multiple books and appeared in var‐
ious videos. Nate is a seasoned speaker, regularly presenting at con‐
ferences worldwide, No Fluff Just Stuff symposia, meetups,
universities, and user groups. In addition to his day job, Nate is an
adjunct professor at the University of Minnesota, where he teaches
students to embrace (and evaluate) technical change. Driven to rid
the world of bad presentations, Nate coauthored the book Presenta‐
tion Patterns with Neal Ford and Matthew McCullough. Nate
recently published Thinking Architecturally, available as a free down‐
load from VMware.