MEAP Edition
Manning Early Access Program
Spring Microservices in Action
Version 1
Copyright 2016 Manning Publications
For more information on this and other Manning titles go to
www.manning.com
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
welcome
Thank you for purchasing the MEAP for Spring Microservices in Action. It is an exciting time to
be a Spring developer, because the Spring Framework has done something that very few
frameworks have been able to do: stay relevant in the face of constant technical change. As
more and more applications have moved to the cloud, the Spring development community has
responded with Spring Boot and Spring Cloud. These two Spring frameworks will allow you to
quickly build microservices that are ready to be deployed to a private corporate cloud or a
public cloud like Amazon Web Services (AWS) or Pivotal’s CloudFoundry.
You do not have to an in-depth cloud experience to benefit from this book.
To take
advantage of this book you should have an established background in Java and Spring (2-3
years).
Some building web-based services (SOAP or REST) is helpful. Other then that, you
just need a willingness to learn.
I first encountered Spring Boot and Spring Cloud while working as an Integration Architect
at a Fortune 500 financial services company. More and more of my job did not involve building
applications, but rather building services that were going to be deployed to a cloud. I found
existing SOAP-based web services, even Spring-based ones, were tedious and time-consuming
to deliver. The SOAP protocols were complex and difficult to work with. Furthermore, as we
began deploying more and more cloud-based services, the operational infrastructure needed
to keep a services-based application running was immature. I spent many an evening as part
of our critical situation team trying to bring back up an application that had crashed because
of a failure in one or more of the services it depended on.
The concept of a microservice architecture is appealing because it shifts development away
from building heavy services based on the SOAP protocols to a much simpler REST/JSONbased service model where an individual service is very constrained in the work is does.
However, any architecture is only as good as the tools and languages that can implement it.
When I discovered the Spring Boot and Spring Cloud frameworks, I realized that these tools
provided the capabilities I needed to build microservice architectures, while still leveraging my
years of experience with Java and Spring.
I was so impressed with the power these frameworks brought, that it one of the reasons
why I chose to write this book. Books are a labor of love and one the deepest expressions of
an authors experiences and knowledge. I hope you enjoy this book. While it has been a lot
hard work to get to this point in the MEAP, I look forward to hearing your comments and
feedback as you explore this existing technologies with me.
—John Carnell
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
brief contents
1 Welcome to the cloud, Spring
2 Building microservices with Spring Boot
3 Controlling your configuration in the cloud with Spring Cloud Config
4 Service discovery with Spring Cloud, Netflix Eureka, and Ribbon
5 When bad things happen: client-side resiliency patterns with Spring and
Netflix Hystrix
6 Service-level routing with Spring Cloud and Zuul
7 Event processing in the cloud with Spring Cloud Stream
8 Getting ready to launch: getting your Spring Cloud application ready for
deployment
9 Pushing to the cloud: how to leverage AWS and CloudFoundry to deploy
your Spring Cloud applications
APPENDIXES:
A Setting up a desktop cloud: using Docker Machine and Docker Compose
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
1
1
Welcome to the cloud, Spring
This chapter covers
•
What are microservices
•
The drivers for changing to microservices
•
Different patterns of microservice development
•
•
The cloud and how microservices are a great natural fit for cloud applications
How Spring Boot/Cloud supports microservice developments
The one constant in the field of software development is that we as software developers sit in
the middle of a sea of chaos and change. We all feel the churn as new technologies and
approaches appear suddenly on the scene that cause us to re-evaluate how we build and
deliver solutions forour customers. One example of this churn is the rapid adoption by many
organizations of adopting and building applications using microservices.
This book is going to introduce you to the microservice pattern and why you should
consider building your applications with them. We are also going to look at how we can build
microservices using Java and two Spring framework projects: Spring Boot and Spring Cloud.
If you are a Java developer, Spring Boot and Spring Cloud are going to provide an easy
migration path from building traditional monolithic Spring applications to microservice
applications that can be deployed to the cloud.
The concept of a microservice originally crept into the software development community’s
consciousness around 2014. A microservice is ansoftware design approachbased around the
concept of building applications out of very small, loosely coupled and distributed services.
•
Application logic is broken down into very small grained components with well defined
•
Each component has a very small domain of responsibility and is deployed completely
boundaries of responsibility that coordinate together to deliver a solution.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
2
independently of one another. Microservices should have responsibility for a single part
of a business domain. Also a microservice should be reusable across multiple
•
applications.
Microservices communicate based on a few basic principles (notice I said principles, not
standards) and employ a very lightweight communication protocols (e.g. HTTP and
•
JSON) for exchanging data between the service consumer and service provider.
The underlying technical implementation of the service are irrelevant because the
applications always communicate with a technology neutral protocol (JSON is the
common).
•
This means an application built using a microservice application could be
built with multiple languages and technologies.
Microservices by their small, independent and distributed nature allow organizations to
have small development teams with well-defined areas of responsibility. These teams
might work to towards a single goal of delivering an application, but each team is
responsible for only the services they ae working.
I often joke with my colleagues that microservices are the gateway drug for building cloud
applications. You start building microservices because they give you a high degree of flexibility
and autonomy with your development teams, but you and your team quickly find that the
small, independent nature of microservices makes them easily deployed to the cloud. Once the
services are in the cloud, their small size makes its easy to start up large instances of the
same service and suddenly your applications become more scalable and with some
forethought more resilient.
1.1 What is Spring and why it’s relevant to microservices
Spring has become the de-facto development framework for building Java-based applications.
At its core Spring is based on the concept of dependency injection. In a dependency injection
framework that allows you to more easily manage large Java projects by externalizing the
relationship between objects within your application through convention (and annotations)
rather then have those objects have hard-coded to know about it each other.
Spring’s rapid inclusion of features drove its utility and the framework quickly became a
lighter weight alternative for enterprise application Java developers looking for an alternative
to building applications using the J2EE stack. The J2EE stack, while powerful was considered
by many bloat with many features that were never used by the application development
teams. Further, a J2EE application forced you to use a full-blown (and heavy) Java application
server to deploy your applications.
What is amazing about the Spring framework and a testament to its development
community is is ability to stay relevant and re-invent itself. The Spring development team
quickly saw that many development teams were moving away from monolithic applications
where the applications presentation, business and data access logic were packaged together
and deployed as a single artifact.
Instead teams were moving to highly distributed model
where services were being built as small, distributed services that could be easily deployed to
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
3
the cloud. In response to this shift, the Spring development team launched two projects
Spring Boot and Spring Cloud.
Spring Boot is a re-envisioning of the Spring framework. While it embraces core features
of Spring, Spring Boot strips away many of “enterprise” features found in Spring and instead
delivers a framework built geared towards Java-based, REST (Representational State
Transfer) 1 orientated microservices quickly. With a few simple annotations, a Java developer
can build a REST microservice that can be package and deployed without the need for an
external application container.
NOTE
While we will cover REST in more detail in chapter 2, the core concept behind REST is that your
services are invoked via the HTTP protocol, embrace the use of the HTTP verbs (GET, POST, PUT and DELETE) to
represent the core actions of the service and use a very lightweight web orientated data serialization protocol,
like JSON for requesting and receiving data from the service.
Since microservices have become one of the more common architectural patterns for building
cloud-based applications, the Spring development community has given us Spring Cloud. The
Spring Cloud framework makes operationalizing and deploying microservices to a private or
public cloud simple.
components. Spring
Microservice applications are highly distributed with many moving
Cloud
wrappers several popular
cloud management microservice
frameworks under a common framework and makes the use and deployment of these
technologies as easy to use as just annotating your code. We will cover the different
components within Spring Cloud later on in the chapter.
1.2 What you will learn in this book
This book is about building microservice based applications using Spring Boot and Spring
Cloud that can be deployed to a private cloud run by your company or a public cloud like
Amazon, Google or Pivotal.With this book, we will cover with hands-on examples:
•
What is a microservice and what are the design considerations that go into building a
•
microservice-based application
•
How to build microservices using the Spring Boot
•
application, particularly a cloud-based application
•
•
When shouldn’t you build a microservice-based application.
What are the core operational patterns that need to be in place to support microservice
How we can use Spring Cloud to implement these operational patterns
How to take take what we have learned and build a deployment pipeline that can be
used to deploy to multiple cloud providers
1
While we cover REST later on in Chapter 2, it always worthwhile to read Roy Fielding’s PHD dissertation on building REST-based applications
(http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm) is still one of the explanations of REST available.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
4
1.3
Why is this book relevant to you
If you have gotten this far into reading chapter 1, I suspect that:
•
You are a Java developer.
•
You have some kind of background in Spring.
•
You are interested in how you leverage microservices for building cloud-based
•
You want to know if Java and Spring are relevant technologies for building
•
•
You are interested in learning how to build microservice-based applications.
applications.
microservice-based applications.
You are interested to see what goes into deploying a microservice-based application to
the cloud.
I chose to write this book, because while I have seen many good books on the conceptual
aspects of microservices, I could not a find a good Java-based book on implementing
microservices. While, I have always considered myself a programming language polyglot
(knows and speaks several languages), Java is my core development language and Spring has
been the development framework I “reach” for whenever I build a new application. When I
first came across Spring Boot and Spring Cloud, I was blown away. Spring Boot and Spring
Cloud greatly simplified my development life when it came to building microservice based
applications running in the cloud.
Enough talk. I have talked a lot this point with very little code examples. Let’s shift gears
for a moment and walkthrough building a simple microservice using Spring Boot.
1.4 Building a microservice with Spring Boot
I have always been of the opinion that a software development framework is well thought out
and easy to use if it passes what I affectionately call the “Carnell Monkey Test.” If a monkey
like me (the author) can figure out a framework in 10 minutes or less it has promise. That is
how I felt the first time I wrote a sample Spring Boot service. I want you to have to the same
experience and joy. So let’s take a minute to write a simple “Hello World” REST-service using
Spring Boot.
Figure 1.1 shows what our service is going to do and the general flow of how Spring Boot
microservice will process a user’s request.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
5
Figure 1.1 A user calling our Hello World microservice
This example is by no means exhaustive or even illustrative of how you should build a
production-level microservice service, but it should cause you to take a pause.
We are not
going to go through how to setup the project build files or the details of the code until
Chapter2. If you would like to see the maven pom.xml file and the actual code, you can find in
the Chapter 1 section of the downloadable code.
So
for
our
example
we
are
going
to
have
a
single
src/com/thoughtmechanix/application/simple/Application.java
Java
class
call
that will be used to
expose a REST endpoint called /hello.
Listing 1.1 shows the code for our Application.java.
Listing 1.1 Hello World with Spring Boot: A (very) simple Spring Microservice
package com.thoughtmechanix.simpleservice;
import
import
import
import
import
import
org.springframework.boot.SpringApplication;
org.springframework.boot.autoconfigure.SpringBootApplication;
org.springframework.web.bind.annotation.RequestMapping;
org.springframework.web.bind.annotation.RequestMethod;
org.springframework.web.bind.annotation.RestController;
org.springframework.web.bind.annotation.PathVariable;
@SpringBootApplication
@RestController
@RequestMapping(value="hello")
public class Application {
❶
❷
❸
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
6
}
@RequestMapping(value="/{firstName}/{lastName}",
❹
method = RequestMethod.GET)
public String hello( @PathVariable("firstName") String firstName,
@PathVariable("lastName") String lastName) {
return String.format("{\"message\":\"Hello %s %s\"}",
❻
firstName, lastName);
}
❺
}
❶
❷
❸
❹
Tells the Spring Boot framework that this class is the entrypoint for the Spring Boot framework.
Tells Spring Boot we are going to expose the code in this class as a Spring RestController class.
All URLs exposed in this application will be prefaced with /hello prefix.
Spring Boot will expose an endpoint a GET-based REST endpoint that will take two parameters in it firstName and
lastName.
❺ Maps the firstName and lastName parameters passed in on the URL to two variables passed into the hello
function.
❻ Returns a simple JSON string.
In listing 1.1 we are basically exposing a single GET http endpoint that will take two
parameters (firstName and lastName) on the URL and then return a simple a JSON string
that has a JSON payload containing the message “Hello firstName lastName”. So if we were to
call the endpoint /hello/john/carnell on our service(which will be shown shortly) the return
of the call would be:
{“message”:”Hello john carnell”}
So lets actually fire up our service. To do this we are going to go to the command prompt and
issue the following command from the command-line:
mvn spring-boot:run
This command, mvn, will use a Spring Boot plug-in to start the application using an embedded
tomcat server.
Java vs. Groovy and Maven vs. Gradle
The Spring Boot framework has strong support for both Java and the Groovy programming language. You can build
microservices with Groovy and and no project setup. Spring Boot also supports both maven and the gradle build tools.
I have chosen to limit the examples in this book to Java and Maven. As a long-time Groovy and Gradle aficionado, the
author has a healthy respect for the language and the build tool, but in an effort to keep the book manageable and the
material focus, I have chosen to go with Java and Maven to reach the largest audience.
If everything starts correctly, you should see the following from your command-line window:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
7
Figure 1.2 Our Spring Boot Service will communicate the endpoints exposed and the port of the service
If you look closes at the screen shot above in Figure 1.1 you will notice two things. First, a
tomcat
server
was
started
on
port
8080.
Second,
a
GET
endpoint
of
/hello/{firstName}/{lastName} is exposed on the server.
So let’s call our service using a command-line tool called curl and see what is returned.
The curl command to issue is:
curl http://localhost:8080/hello/john/carnell
When the command above is issued, we should see the following response.
Figure 1.3 Response from the /hello endpoint
Obviously this simple example does not demonstrate the full power of Spring Boot. But what
it should show is that you can write a full HTTP JSON REST-based service with route mapping
of URL and parameters in Java with as little as 25 lines of code.
As any experienced Java
developer will tell you, writing anything meaningful in 25 lines of code in Java is extremely
difficult. Java, while being a very powerful language, has acquired a reputation of being wordy
compared to other language. 2
We are done with our brief tour of Spring Boot and will cover it in more detail in Chapter 2.
However, just because we can write our applications using a microservice approach, does this
mean we should?
In the next section we are going to walkthrough why and when a
microservice approach is justified for building your applications.
2
Shhh don’t tell anyone, but this Java programmer has a habit of also writing Clojure code. That’s a book for another day
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
8
1.5 Why change the way we build applications?
We are at an inflection point in history. Almost all aspects of modern society are now wired
together via the Internet. Companies that used to serve local markets are suddenly finding
that they can reach out to a global customer base. However, with a larger global customer
base has also come global competition.
These competitive pressures mean the following
forces are impacting the way developers have to think about building applications:
•
Complexity has gone way up.
Customers expect that all parts of an organization
know who they are. “Siloed” applications that talk to a single database are no longer
the norm. Today’s applications need to talk to multiple services and database residing
not only inside a company’s data center, but also to external service providers over the
•
Internet.
Customers want faster delivery. Customers no longer want to wait annually for the
next release or version of a software package. Instead, they expectthe features in a
software product to be unbundled so that new functionality can be released without
•
having to wait for an entire product release.
Performance and scalability.
Global applications make it extremely difficult to
predict how much transaction volume is going to be handled by an application and
when that transaction volume is going to hit. Applications need to be able to scale up
across multiple servers quickly and then when the volume needs have passed, scale
•
back down.
Customers expect their applications to be available.
Since, customers are one
click away from a competitor, a company’s applications must be highly resilient.
Failures or problems in one part of the application should not bring down the entire
application.
To meet the expectations listed above, we as application developers have to embrace the
paradox that to build high-scalable and highly redundant applications we need to break our
applications into very small services that can be built and deployed independently of one
another.
If we “unbundle” our applications and move them away from a single monolithic
artifact we can build systems that are:
•
Flexible.
Decoupled services can be composed and rearranged to quickly deliver new
functionality. The smaller the unit of code that one is working with the less complicated
•
it is to change the code and the less time it takes to test deploy the code.
Resilient. Decoupled servicesmeans an application is no longer a single “ball of mud”
where a degradation in one part of the application causes the whole application to fail.
Failures can be localized to a small part of the application and contained before the
entire application experiences an outage. This also enables the applications to degrade
•
gracefully in case of un-recoverable error.
Scalable.
Decoupled servicescan easily be distributed horizontally across multiple
servers enabling the ability to scale the features / services appropriately. With a
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
9
monolithic application where all of the logic for the application is intertwined the entire
application needs to scale even if only a small part of the application is the bottleneck.
Scaling on small services are localized and much more cost-effective.
To this end as we begin our discussion of microservices keep the following in mind:
SMALL, SIMPLE AND DECOUPLED SERVICES
=
SCALABLE, RESILIENT AND FLEXIBLE APPLICATIONS
1.6 What exactly is the cloud
The term “cloud” has become overused. Every software vendor has a cloud and everyone’s
platform is cloud-enabled, but if you cut through the hype there are really three basic models
of cloud-based computing. These are:
•
•
•
Infrastructure as a Service
Platform as a Service
Software as a Service
To better understand these concepts let map the everyday task of making a meal to how a
different models of cloud computing.
When we want to eat a meal we have four choices:
1. We can make the meal at home.
2. We can go to the grocery store and buy a meal pre-made that we have to heat up and
server.
3. We can a meal delivered to our houses
4. We can get in the car and eat at restaurant.
Figure 1.4 shows each model:
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
10
Figure 1.4 The three core models of cloud computing
The difference between these options is really about whose responsible for cooking these
meals and where the meal is going to be cooked. In the on-premise model, eating a meal at
home requires you to do all of the work using your own oven and ingredients already in the
home. A store-bought meal is like using the Infrastructure as a Service (IaaS) model of
computing. We are using the store’s chef and oven to pre-bake the meal, but we still are still
responsible for heating the meal and eating it at house (and cleaning up the dishes
afterwards).
In a Platform as a Service (PaaS) model we still have some responsibilities for the meal
(e.g. we have to supply the plates and furniture), but we further rely on a vendor to take care
of the core tasks associated with making a meal. In the Software as a Service (SaaS) model,
we go to a restaurant where all the food is prepared for us. We eat at the restaurant and then
we pay for the meal when we are done. We also have no dishes to prepare.
The key items at play in each of these models is one of control: who is responsible for
maintaining the infrastructure and what are the technology choices available for building an
application.
1.7 Why the cloud and microservices
One of the core concepts of a microservice-based architecture is that each service is packaged
and deployed as is its own discrete and independent artifact.
Services instance should be
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
11
able to brought up quickly and each instance of the service should be indistinguishable from
each other.
As a developer writing a microservice sooner or later you are going to have to decide
whether your service is going to be deployed to a:
•
Physical Server.
While you can build and deploy your microservices to a physical
machines few organizations do this because physical servers are constrained. You can
not quickly ramp up the capacity of a physical server and scaling horizontally your
•
microservice across multiple physical servers can become extremely costly.
Virtual Machine Images. One of the key benefits of microservices is being able to
quickly startup and shutdown microservice instances in response to scalability and
service failure events.
providers.
Virtual machines are the heart and soul of the major cloud
A microservice can be packaged up in a virtual machine image.
Multiple
instances of the service can then be quickly deployed and started in either a IaaS
•
private or public cloud.
Virtual Container.
Virtual container are a natural extension to deploying your
microservices on a virtual machine image. Rather then deploying your service to a full
virtual machine, many developers will deploy their services as Docker (or equivalent
container technology) containers to the cloud. Virtual containers run inside of a virtual
machine and allow you to segregate a single virtual machine into a series of selfcontained processes sharing the same virtual machine image.
For this book, all the microservices and corresponding service infrastructure will be deployed
to an IaaS-based cloud provider.
This is the most common deployment topology used for
microservices:
•
Simplified Infrastructure Management. IaaS cloud-providers give you the ability to
have the most control over your services. New services can be started and stopped
with simple API calls. With an IaaS cloud solution, you only pay for the infrastructure
•
that you use.
Massive horizontal scalability.
IaaS cloud providers allow you to quickly and
succinctly start service (and their corresponding services). This capability means you
can scale services quickly and also allows you to quickly route around misbehaving or
•
failing servers.
High redundancy through geographic distribution.
By necessity IaaS providers
will have multiple data centers. By deploying your microservices using an IaaS cloud
provider you can gain a higher level of redundancy beyond just using cluster in a data
center.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
12
Whynot PaaS-based Microservices?
Earlier in the chapter we identified there are three types of cloud platforms (Infrastructure as a Service, Platform as a
Service and Software as a Services). For this book we have chosen to focus specifically on building microservices using
an IaaS-based approach. While some cloud providers will let you abstract away the deployment infrastructure for your
microservice.
For instance, Amazon, CloudFoundry and Heroku give you the ability to deploy your services without having to know
about the underlying application container. They provide a web interface and APIs to allow you to deploy your
application as a WAR or JAR file. The setup and tuning of the application server and the corresponding Java container
are abstracted away from you. While this is very convenient, each cloud provider’s platform have different
idiosyncracies related to their individual PaaS solution.
An IaaS approach, while more work, is portable across multiple cloud providers and also allows us to reach a wider
audience with our material. Personally, I have found that PaaS based cloud solutions can allow you to quickly jump
start your development effort, but once your application reaches enough microservices, you starting needing the
flexibility the IaaS style of cloud development provides.
The services built in this book will be packaged as Docker containers. One of the reasons why
I chose Docker is that as a container technology, Docker is deployable to all of the major cloud
providers.
Later in Chapters 8 and 9, I will be demonstrating how to package our
microservices using Docker and then deploy these containers to Pivotal’s and Amazon’s cloud
platforms. (CloudFoundry and Amazon Web Services respectively)
1.8 Microservices are more then just writing the code
While the concepts around building individual microservices are easy to understand, actually
running and supporting a robust microservice application (especially when running in the
cloud) involves a lot more then writing the services code.
It involves having to think about
how your services are going to be:
•
Right-sized. How do we ensure that our microservices are properly sized so that we
do not have a microservice take on too much responsibility? Remember, properly size
a service allows us to quickly make changes to an application and reduces the overall
•
risk of an outage to the entire application?
Manageable.How do we manage the physical details of service invocation when in a
microservice application you might have multiple service instances can quickly start
•
and shutdown?
•
application by routing around failing services and ensuring that we take a “fail-fast.”
Resilient. How do protect our microservice consumers and the overall integrity of our
Repeatable. How do we ensure that every new instance of our service brought up is
guaranteed to have the same configuration and code base as all the other service
•
instances in production?
Scalable. How do we leverage asynchronous processing and events to minimize the
direct dependencies between our services and ensure that we can gracefully scale our
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
13
microservices?
This book is going to take a patterns based approach as we answer the questions above.
Specifically, we are going to cover the following four categories of patterns:
•
•
•
•
Core Microservice Development Patterns
Microservice Routing Patterns
Microservice Client Resiliency Patterns
Microservice Build/Deployment Patterns
Let’s walk through these patterns in more detail.
1.8.1 Core Microservice Development Pattern
The core development patterns really deals with the basics of building a microservice. Figure
1.5 highlights the topics we will cover around basic service design.
Figure 1.5 – In building a simple service we have to consider these topics
Let’s walk through these topics in a little more detail.
•
Service Granularity.
How do you approach decomposing a business domain down
into microservices so that the microservice has the right level of responsibility? Making
a service too coarse-grained with responsibilities that overlap into different business
problems domains makes service difficult to maintain and change over time. Making
the service too fine-grained increases the overall complexity of the application and
really just turns the service into a data later.
Service granularity will be covered in
chapter 2.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
14
•
Communication Protocols. How will developers communicate with your service? We
will go into why JSON is the ideal chose for microservices and has become the most
common choice for sending and receiving data to microservice.
•
The topic of
communication protocols will be covered in Chapter 2 of this book.
Interface Design. What is the best way to design the actual service interfaces that
developers are going to use to call your service? How do you structure your service
URLs to communicate service intent?
What about versioning your services? A well
design microservice interface makes using your service intuitive. Interface design will
•
be covered in Chapter 2.
Configuration Management of Service.
How do you manage the configuration of
your microservice so that as it moves between different environments in the cloud you
never have to change the core application code or configuration?
•
Managing service
configuration will be covered in Chapter 3.
Event processing between services. How do you decouple your microservice using
events so that you minimize hardcoded dependencies between your services and
increase the resiliency of your application?
The topic of event processing between
services will be covered in chapter 7.
1.8.2 Microservice Routing Patterns
The microservice routing patterns cover microservice discovery and routing. In a cloud-based
application you might have hundreds of microservices instances running. This means you will
need to abstract away the physical IP address of these services and have a single point of
entry for service calls so that you can consistently enforce security and content policies for all
service calls.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
15
Figure 1.6 – Service discovery and routing are key parts of any large-scale microservice application.
Service discovery and routing really answer the question of how do I get my clients request
for a service to a specific instance of a service.
•
Service Discovery.
How do you make your microservice discoverable so client
applications can find them without having the location of the service hardcoded into the
application? How do you ensure that misbehaving microservice instances are removed
•
from pool of available service instances? Service discovery is covered in Chapter 4.
Service Routing – How do provide a single entry point for all of your services so that
security policies and routing rules are applied uniformly to multiple services and service
instances in your microservice applications? How do you ensure that each developer in
you team do not have to come up with their own solutions for providing routing to their
services. Service routing is covered in chapter 6.
While in Figure 1.3 appear to have a hard-coded sequence between them (first comes service
routing and the service discovery) to implement one pattern does not require the other. For
instance, we can implement service discovery without service routing. Service routing can be
implemented without service discovery (even though its implementation is more difficult)
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
16
1.8.3 Microservice Client Resiliency Patterns
Since microservices architectures are highly distributed we have to be extremely sensitive in
how we prevent a problem in single service (or service instance) from cascading up and out to
the consumers of the service. To this end, we are going to cover four topics with client
resiliency patterns.
Figure 1.7 – With microservices care must be taken to protect the call from a poorly behaving services
•
Client-side load balancing. How do we cache the location of our service instances on
the service client so that calls to multiple instances of a microservice are load balanced
•
to all of the health instances of that microservice?
Circuit Breakers Pattern.
How do you prevent a client from continuing to call a
service that is failing or suffering performance problems? When a service is running
slow it consuming resources on the client calling it. We want failing microservice calls
•
to fail fast.
Fallback Pattern. When a service call fails how do we provide a “plug-in” mechanism
that will allow the service client to try and carry out its work through some alternatives
•
means other then the microservice being called.
Bulkhead Pattern.Microservice applications use multiple distributed resources to carry
out their work. How do we compartmentalize these calls so that the misbehavior of one
service call does not negatively impact the rest of the application?
These four topics are covered in Chapter 5.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
17
1.8.4 Microservice Build/Deployment Patterns
One of the core parts of a microservice architecture is that each instance of a
microservice should be identical to all of its other instances. We can not allow “configuration
drift” (something changes on a server after it has been deployed) to occur as this can
introduceinstability in your applications.
A phrase too often said
“I made only one small change on the stage server, but I forgot to make the change in production.” The resolution of
many down systems when I have worked on critical situations teams over the years has often started with those words
from a developer or system administrator. Engineers (and most people in general) operate under the notation of good
intent. They don’t go to work to make mistakes or bring down systems. Instead they are doing the best they can, but
they get busy or distracted. So they tweak something on a server fully intending to go back and do it in all of the
environments.
At some later point, an outage occurred and everyone is left scratching their head going what is different between
the lower environments in production. I have found that the small size and limited scope of microservice make it the
perfect opportunity to introduce the concept of “immutable infrastructure” into an organization: Once a service is
deployed, the infrastructure it is running on is never touched again by human hands
In my mind having an immutable infrastructure is critical piece of successfully using a microservice architecture,
because you have to be able to guarantee in production that every microservice instance you start for a particular
microservice is identical to its brethren.
To this end our goal is to integrate the configuration of our infrastructure right into our build
deployment process so that we no longer deploy software artifacts like a Java WAR our EAR to
an already running piece of infrastructure. Instead we want to “bake” our microservice and
the virtual server image it is running on as part of the build process. Then when our
microservice gets deployed, the entire machine image with the server running on it gets
deployed.
Figure 1.8 illustrates this process.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
18
Figure 1.8 We want to deployment of the microservice and the server its running on to be one atomic artifact
that is deployed as a whole between environments.
At the end of the book we are going to look at how we change our build and deployment
pipeline so that our microservices and the servers they run on are deployed as a single unit of
work. In chapter 8 we are going to cover the following patterns and topics:
•
Build and Deployment Pipeline.
How do you create a repeatable build and
deployment process that emphasis one button builds and deployment to any
environment in your organization?
•
Infrastructure as Code. How do you treat the provisioning of your services as code
•
Immutable Servers.
•
Phoenix Servers.
that can be executed and managed under source control?
Once a microservice image is created how do you ensure that it
is never changed after it has been deployed?
The longer a server is running the more opportunity for
configuration drift. How do we ensure that our servers that run our microservices get
torn down on a regular basis and recreated off an immutable image?
Our goal with these patterns and topics is to ruthlessly expose as quickly as possible and
stamp out configuration drift before it is allowed to hit our environment upper environments
like stage or production.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
19
1.9 Leveraging Spring Cloud in building your microservices
In this section, I briefly introduce the Spring Cloud technologies that we are going to use as
we build out our microservices. This is just a high-level overview; when we use each
technology in this book, I’ll teach you the details on each as needed.
Implementing all of the patterns above from scratch would be a tremendous amount of
work.
Fortunately, for us the Spring team has integrated a wide number of battle-tested
open-source
projects into a
Spring
sub-project
collectively
known
as Spring
Cloud.
(http://projects.spring.io/spring-cloud/).
Spring Cloud wrappers the work of open-source companies like Pivotal, HashiCorp and
NetFlix in delivering the above patterns. Spring Cloud simplifies setting up and configuring of
these projects into your Spring application so that you can focus on writing code and not
getting buried in the details of configuring all of the infrastructure that can go with building
and deploying a microservice application.
Figure 1.8 below maps the patterns listed in the previous section to the Spring Cloud
projects that implement them.
Figure 1.9 Mapping the technologies we are going to use to implement the microservice patterns
Let’s walkthrough these technologies in greater detail.
1.9.1 Spring Boot
Spring Boot is the core technology used in our microservice implementation.
Spring Boot
greatly simplifies microservice development by simplifying the core tasks of building RESTbased microservices. Spring Boot greatly simplifies mapping HTTP-style verbs actions to URLs
and the serialization of the JSON (JavaScript Object Notation) protocol to and from Java
objects. It also simplifies the mapping of Java exceptions back to standard HTTP error codes.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
20
1.9.2 Spring Cloud Config
Spring Cloud Config handles the management of application configuration data through a
centralized service so your application configuration data (particularly your environment
specific configuration data) is cleanly separated from your deployed microservice.
This
ensures that no matter how many microservice instances you bring up they will always have
the same configuration.
Spring Cloud Config has it owns property management repository,
but also integrates with open source projects like Git (https://git-scm.com/) , Consul
(https://www.consul.io/) and Eureka project (https://github.com/Netflix/eureka).
1.9.3 Spring Cloud Service Discovery
Spring Cloud service discovery allows you to abstract away the physical location (IP and/or
server name) of where your servers are deployed from the clients consuming the service.
Service consumers invokes business logic for the servers through a logical name rather then a
physical location.
Spring Cloud Service Discovery also handles the registration and
deregistration of services instances as they are started up and shutdown.
Spring Cloud
Service Discovery can be implemented using Consul (https://www.consul.io/) and Eureka
project (https://github.com/Netflix/eureka)as it service discovery engine.
1.9.4 Spring Cloud/Netflix Hystrix and Ribbon
Spring Cloud heavily integrates with Netflix open source projects.
resiliency
patterns,
Spring
(https://github.com/Netflix/Hystrix)and
Cloud
Ribbon
wrappers
the
For microservice client
Netflix
Hystrix
(https://github.com/Netflix/Ribbon)projects
and makes leveraging them from within your own microservices trivial to implement.
The
Netflix Hystrix libraries allow you quickly implement service client resiliency patterns like the
circuit breaker and bulkhead patterns.
While the Netflix Ribbon project simplifies integrating with service discovery agents like
Eureka, it also provides client-side load-balancing of service calls from a service consumer.
This allows a client to continue making service calls even if the service discovery agent is
temporarily unavailable.
1.9.5 Spring Cloud/Netflix Zuul
Spring Cloud leverages the Netflix Zuul project (https://github.com/Netflix/zuul)to provide
service routing capabilities for your microservice application. Zuul proxies service request and
makes sure that all calls to your microservices go through a single “front door” before the
actual requests hits your service instance. This centralization of service calls with Zuul allows
you to enforce standard service policies like a security authorization authentication, content
filtering and routing rules.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
21
1.9.6 Spring Cloud Stream
Spring Cloud Stream (https://cloud.spring.io/spring-cloud-stream/) is an enabling technology
that allows you easily integrate lightweight message processing into your microservice.
By
using Spring Cloud Stream you can build intelligent microservices that can leverage
asynchronous events as they occur in your application. Spring Cloud Stream allows to quickly
integrate your microservices with AMQP-compliant (https://www.amqp.org/)message brokers
like RabbitMQ (https://www.rabbitmq.com/)and Kafka.(http://kafka.apache.org/)
1.9.7 What about Provisioning?
For the provisioning implementations we are going to make a technology shift.
The Spring
framework(s) are geared towards application development. The Spring frameworks (including
Spring Cloud) do not have tools for creating a “build and deployment” pipeline. To this end we
are going to leverage the following tools:
Travis CI (https://travis-ci.org) for our build tool
and Docker (https://www.docker.com/) to build the final server image containing our
microservice.
1.10 Spring Cloud by example
In the last section we walked through all the different Spring Cloud technologies that we are
going to use as we build out our microservices.
Since each of these technologies are
independent services it is obviously going to take more than one chapter to explain all of them
in detail. However, as I wrap up this chapter, I want to leave you with a small code example
that again demonstrates how easy it is to integrate these technologies in your own
microservice development effort.
Unlike the first code example in listing 1.1, you will not be able to simply run this code
example, as there are a number of supporting services that need to be setup and configured
to be leveraged.
Don’t worry though, the setup costs for these Spring Cloud services
(configuration service, service discovery) are a one-time cost in terms of setting up the
service.
Once they are setup, your individual microservices can leverage these capabilities
over and over again.
We just get fit all that goodness into a single code example at the
beginning of the book.
In the code showing in listing 2.2, I am going to quickly demonstrate how we integrated
the service discovery, the circuit breaker, bulkhead and client-side load balancing of remote
services into our “Hello World” example.
Listing 1.2 Our Hello World Service using with Spring Cloud
package com.thoughtmechanix.simpleservice;
//Removed other imports for conciseness
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
22
import
org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
@SpringBootApplication
@RestController
@RequestMapping(value="hello")
@EnableCircuitBreaker
@EnableEurekaClient
public class Application {
❶
❷
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@HystrixCommand(threadPoolKey = "helloThreadPool")
❸
public String helloRemoteServiceCall(String firstName,
String lastName){
ResponseEntity<String> restExchange =
restTemplate.exchange(
"http://nameservice/name/{firstName}/{lastName}", ❹
HttpMethod.GET,
null, String.class, firstName, lastName);
return restExchange.getBody();
}
@RequestMapping(value="/{firstName}/{lastName}",
method = RequestMethod.GET)
public String hello( @PathVariable("firstName") String firstName,
@PathVariable("lastName") String lastName) {
return helloRemoteServiceCall(firstName, lastName)
}
}
Listing 1.2 Our simple service leveraging Spring Cloud Capabilities
❶ Enables the service to use the Hystrix and Ribbon Libraries
❷ Tells the service that it should register itself with a Eureka service discovery agent and that service calls are to use
Service discovery to “lookup” the location of remote services
❸ Wrappers calls to the helloRemoteServiceCall method with a Hystrix Circuit Breaker.
❹ Uses a decorated RestTemplate class to take a “logical” service id and use Eureka under the covers to look up
the physical location of the service.
There is a lot packed into the code example above. Let’s quick walkthrough it. Keep in mind
that listing 1.2 is for examples purposes only. We will structure and break apart our Spring
Boot microservices into a more structured fashion as we progress through the book.
The first thing you should notice as you look at listing 1.2, is the @EnableCircuitBreaker
and @EnableEurekaClient annotations.
The @EnableCircuitBreaker annotation tells our
Spring microservice that we are going to use the Netflix Hystrix libraries in our application.
The @EnableEurekaClient annotation tells our microservice to register itself with a Eureka
Service Discovery agent and that we are going to use service discovery to look up remote
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
23
REST services endpoints in our code. Note, there is some configuration going on in a property
file that will tell our simple service the location and port number of a Eureka server to
contact.We first see Hystrix being used when are declaring our hello method.
@HystrixCommand(threadPoolKey = "helloThreadPool")
public String helloRemoteServiceCall(String firstName, String lastName)
The
@HystrixCommand
annotation
is
doing
two
things.
First,
any
time
the
helloRemoteServiceCall method, the method will be invoked on a thread pool managed by
Hystrix. If the calls takes too long (default is 1 second), Hystrix will step in and interrupt the
call.
This is the implementation of the circuit breaker pattern.
The second thing this
annotation does is create a thread pool called “helloThreadPool” that is managed by Hystrix.
All calls to helloRemoteServiceCall method will only occur on this thread pool and will be
isolated from any other remote service calls being made.
The last thing to note is what is occurring inside the the helloRemoteServiceCall
method. The presence of the @EnableEurekaClient has told Spring Boot that we are going
to use to a modified RestTemplate class (this is not how the Standard Spring RestTemplate
would work out of the box) whenever we make a REST service call. This RestTemplateclass
will allow us to pass in a logical service id for the service we are trying to invoke.
ResponseEntity<String> restExchange =
restTemplate.exchange(http://logical-serviceid/name/{firstName}/{lastName}
Under the covers, the RestTemplate class will contact the Eureka service and lookup the
physical location of one or more the “name” service instances. As a consumer of the service,
our code never has to nowhere that service is located.
Also RestTemplate class above is leveraging Netflix’s Ribbon library. Ribbon will retrieve a
list of all of the physical endpoints associated with a service and the everytime the service is
called by the client, will round robin to the different service instances on the client without
having to go through a centralized load balancer. By eliminating a centralized load-balancer
and moving it to the client you eliminate another failure point (load balancer going down) in
your application infrastructure.
I hope at this point you are impressed because we have added a significant amount of
capabilities to our microservice with only a few annotations. That is the real beauty behind
Spring Cloud.
You as a developer get to take advantage of battle-hardened microservice
capabilities from premier cloud companies like Netflix and Consul.
These capabilities, if be
being used outside of Spring Cloud can be complex and obtuse to setup.
Spring Cloud
simplifies their use down to literally nothing more then a few simple Spring Cloud annotations
and configuration entries.
1.11 Making sure our examples are relevant
I want to make sure this book provides examples that you can relate to as you go about your
day-to-day job. To this end, I am going to structure the chapters in this book and the
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
24
corresponding code examples around the adventures (misadventures) of a fictitious company
called ThoughtMechanix. The examples in this book will not build the entire ThoughtMechanix
application. Instead we build some specific microservices from the problem domain at hand
and then build the infrastructure that will support these services
ThoughtMechanix is a software development company, whose core product, EagleEye
provides an enterprise grade Software Asset Management application. It provides coverage for
all of the critical elements: Inventory, Software Delivery, License management, Compliance,
Cost and Resource management. Its primary goal is to enable organizations to gain an
accurate point in time picture of its software assets.
The company is approximately 10 years old and while they have been experiencing solid
revenue growth internally they have been debating about whether or not they should be replatforming their core product from a monolithic,“on premise” based application or move their
application to the cloud. The re-platforming involved with EagleEye can be a “make or break”
moment for a company. The company is looking at rebuilding their core product EagleEye on a
new architecture. While much of the business logic for the application will remain in place, the
application itself will be broken down from a monolithic design to a much smaller microservice
design whose pieces can be deployed independently to the cloud.
The ability to successfully adopt cloud-based, microservice architecture is going to impact
all parts of a technical organization. This includes the architecture, engineering, testing and
operations teams. Input is going to be needed from each group and in the end they are
probably going to see the need for some reorganization as the team re-evaluates their
responsibility in this new environment. Let’s begin our journey with Thoughtmechanix as we
begin the fundamental work of identifying and building out some of the microservices used in
“Eagle Eye” and then building these services using Spring Boot.
1.12 Summary
•
•
Microservices are extremely small pieces of functionality that are responsible for one
specific area of scope.
There are no industry standards around microservices. Unlike other early web service
protocols, microservices take a principle based approach and align with the concepts of
•
REST and JSON.
Writing microservices are easy, but fully operationalizing them for production requires
additional forethought. We introduced several categories of microservice development
patterns
including:
core
development,
routing
patterns,
client
resiliency
and
build/deployment patterns.
•
While microservices are language agnostic, we introduced two Spring frameworks that
•
Spring Boot is used to simplify the building of REST-based/JSON microservices.
significantly help in building microservices: Spring Boot and Spring Cloud.
Its
goal is to allow you to build microservices quickly with nothing more then a few
annotations.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action
25
•
Spring Cloud is a collection of open-source technologies from companies like NetFlix
and HashiCorp that have been “wrappered” with Spring annotations to significantly
simplify the setup and configuration of these services.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
https://forums.manning.com/forums/spring-microservices-in-action