October 28, 2015
Building a Microservice Architecture with Spring Boot and Docker, Part I
This is the first post in what will be a 4-part series on building a microservice architecture with Spring Boot & Docker. This post will provide an overview of what we mean when we talk about a microservice architecture, as well as the concept of containerization.
Part 1: Overview of Microservice Architecture & Containerization
What's all of the hoopla about microservices?
As more products are being built around reusable REST-based services, it has been quickly discovered that splitting out your business functions into reusable services is very effective, but also introduces a risk point. Every time you update a service, you have to re-test every other service that is deployed along with it -- even if you're confident the code change wouldn't impact the other service, you could never really guarantee it because the services inevitably share code, data, and other components.
With the rise of containerization, you can run code in complete isolation very efficiently; combining these two together allows for a product architecture that optimizes for fine-grained scalability and versioning, but at the cost of increased complexity and some duplicated code.
Isn't containerization just the "new" virtualization?
Not exactly. It does share some similarity, in that containers and virtual machines are isolated environments that are managed by a controlling process (container manager and hypervisor respectively), but the primary difference between the two is that for each virtual machine, an entire stack of components are running -- the Operating system up to the application server, and virtual hardware is emulated including network components, CPUs, and memory.
For containers, they operate more as fully isolated sandboxes, with only the minimal kernel of the operating system present for each container. The system resources of the underlying system are shared. The biggest advantage of containerization is the substantially smaller footprint means that for the same hardware, substantially more containers can be run than virtual machines. There are some key limitations of containers: the biggest one is that containers can only run Linux-based operating systems (this kernel isolation is Linux-specific technology).
Related to this limitation is that running Docker - the most popular container provider system -- doesn't run directly on Mac or Windows systems because they are not Linux. Instead, to run Docker containers, you need to start up a Linux Virtual Machine using VirtualBox, then run the Docker containers inside this virtual machine. Fortunately, the vast majority of this is managed by Docker Toolbox (formerly known as boot2docker).
Docker has received so much traction that the public repository of container images, Docker Hub, contains over 136,000 public images. Many of these are created by private individuals, some extending "official" images and customizing them to their needs, but others are entire platform configurations customized from "base" images. We will be leveraging some of these "base" and "official" container images for our study.
So we've talked microservices and containerization, but what part does Spring Boot play?
I've chosen to build my microservices using Java, specifically the Spring Boot framework. This was primarily chosen due to being familiar with Spring, and the ease of developing REST-service controllers, business services, and data repositories with it. This could just as easily be done in Scala with Akka/Play; one of the touted benefits of microservice architecture is full independence of the services, so it shouldn't matter what language or platform each is built and deployed in.
Personally, I think the maintenance costs of developing with multiple languages is greater than the gains of flexibility, but there are applicable use cases, such as one could be in a situation where one department within a large organization has chosen different technology stacks as "standard." Another possible scenario where this benefit would apply is if you decide to transition from one language/platform to another -- you can migrate one microservice at a time, provided the end web service interface remains the same. Some goals for this effort:
- A start-to-finish guide to setting up microservices and Docker
- Understanding the pros and cons of different decisions around the components surrounding this architecture -- from source control to service versioning, and everything in between
- Analyze "purist" microservice beliefs and see how they hold up when applied to a "real world" scenario
- See if Docker lives up to the hype, and what is necessary to run Docker for professional development
- Build a complete solution utilizing a series of microservices, each in its own container; a persistent layer, hosted in its own container; container clustering
- Have fun
The business scenario that I will model is an employee tasking and recognition system at a software development company. The system covers the following tasks:
- Employees log into the system
- Employees see a list of required tasks/missions, e.g. write a blog post on emerging technology, attend a conference, perform code review
- Employees submit completion of these tasks to their manager for approval
- Employees receive "points" for completing tasks
- Employees can spend points on rewards like company swag, free lunch 1:1 meeting CEO, etc.
This closes out part I pretty well -- we have the beginnings of an understanding around microservices, containerization, and a business scenario that we will use as a backdrop for the rest of the discussions. As we move onto part II, we'll get set up with tooling and dive into how to work with Docker and setting up our first container.
This blog is the first of four parts: