Nearly every computer system performs multiple tasks using shared resources, and one of the questions of computer programming is how closely the bits of code that perform those tasks should be tied to one another. An increasingly popular answer is the concept of a microservice—a small, discrete chunk of functionality that interacts with other microservices to create a larger system.
Although the basic idea of having such discrete components isn’t new, the way microservices are implemented makes them a natural foundation for both modern cloud-based applications. Microservices also dovetail with the devops philosophy, which encourages rapidly and continuously rolled out new functionality.
What are microservices?
The “micro” in microservices implies that these are small applications. That’s sometimes true, but a better way to think about them is that they should be only as big as needed to do one specific thing or solve a particular problem. That problem should be conceptual, not technical. As , “Microservices should be designed around business capabilities, not horizontal layers such as data access or messaging.” They communicate with other microservices and outside users via relatively stable APIs to create a larger application.
Thus, the internal functionality of an individual microservice can be tweaked or radically upgraded without affecting the rest of the system. This in turn ties into how devops shops seek to operate: If the specific functions of a larger application are segmented out into discrete, independently operating pieces of code, it’s easier to live the devops mantra of CI/CD (. Also, well-defined APIs makes microservices easy to automatically test.
Microservices architecture vs. monolithic architecture
You’ll often hear microservices talked about in terms of a “microservices architecture.” This phrase encompasses not just the microservices themselves, but , as well as an API gateway that handles communication between microservices and the outside world.
A “monolithic application” is the opposite of what microservices are. It’s a for an application where all the code is in one large binary executable file. As TechTarget explains, a monolithic application is . But because it’s built as a single cohesive application, it doesn’t require as much management as a microservices architecture.
, you create an abstract model of your business domain, and in the process discover the bounded contexts, which group together functionality that interacts with the world in a specific way.
For instance, you might have one bounded context for shipping and another for accounts. A real-world physical object would have both a price and a place it needs to go, of course, but the bounded contexts represent specific ways in which your application thinks about and interacts with those objects. Each microservice should exist entirely within a single bounded context, though some bounded contexts might encompass more than one microservice.
, but here’s a short version:
- In a service-oriented architecture, individual components are relatively tightly coupled, often sharing assets such as storage, and they communicate through a piece of specialized software called an enterprise storage bus. Microservices are more independent, share fewer resources, and communicate via more lightweight protocols. It is worth noting that microservices arose out of the SOA milieu, and are sometimes considered a kind of SOA, or successor to the concept.
- A Web service is a publicly facing set of functionality that other applications can access via the Web; probably the most prevalent example is Google Maps, which a restaurant’s website could embed to provide directions for customers. This is a much looser connection than you’d see in a microservices architecture.
A catchphrase you’ll often hear used about microservices architectures is that they should feature “.” In other words, microservices should aim to use basic and well-established communication methods rather than complex and tight integration. As noted, this is another thing that distinguishes microservices from SOA.
In general, communication between microservices should be , in the sense that code threads aren’t blocked waiting for responses. (It’s still fine to use synchronous communications protocols such as HTTP, though asynchronous protocols such as AMQP (Advanced Message Queuing Protocol) are also common in microservices architectures.) This kind of loose coupling makes a microservices architecture more flexible in the face of the failure of individual components or parts of the network, which is a key benefit.
Microservices, Java, and Spring Boot and Spring Cloud
Some of the first work in microservices arose in the Java community; was an early proponent. A 2012 Java conference in Poland featured one of the most important early presentations on the subject, entitled “.“ It recommended applying the principles that guided the development of the first Unix applications in the 1970s (“Write programs that do one thing and do it well. Write programs to work together”) to Java development.
Microservices and containers: Docker, Kubernetes, and beyond
The underlying technology that has gone furthest towards getting microservices into the mainstream is containers. A container is similar to a VM instance, but instead of including an entire self-contained OS, a container is just an isolated user space that makes use of the host operating system’s kernel but otherwise keeps the code executing inside of it self-contained. Containers are much smaller than VM instances and are easy to quickly deploy, either locally or in the cloud, and can be spun up or down to match demand and available resources.
The appeal of containers for microservices should be obvious: Each individual microservice can run in its own container, which cuts the overhead of managing services significantly. Most container implementations have complementary orchestration tools that automate the deployment, management, scaling, networking, and availability of container-based applications. It’s the combination of small, easy-to-build microservices and easy-to-deploy containers that . There are several implementations of the container concept, but by far the most popular is , which is generally paired with as an orchestration platform.
Spring, while popular, is tied to the Java platform. Container-based systems, on the other hand, are polyglot: Any programming language that the OS supports can run in a container, which gives more flexibility to programmers. Indeed, a big advantage of microservices is that each individual service can be written in whatever language makes the most sense or that developers are most comfortable with. Indeed, a service could be completely rebuilt in a new language without affecting the system as a whole, as long as its APIs remain stable. DZone has an article discussing the for microservices.
Microservices design patterns
No matter what language you use to develop microservices, you’ll face issues that other developers have encountered before. Design patterns are formalized, abstract solutions to recurring problems in computer science, and a number of them are specifically for microservices. , which includes:
- Service Registry: for connecting clients to available instances of microservices
- Circuit Breaker: to prevent failed services from being called repeatedly
- Fallback: for providing an alternative to a failed service
- Sidecar: for providing an auxiliary service to the main container, such as for logging, synchronizing services, or monitoring
- Adapter: to standardize or normalize the interface between the main container and the external world
- Ambassador: to connect the main container to the outside world, such as for proxying localhost connections to outside connections
Microservices and the cloud: AWS and Azure
As noted above, one of the advantages of using containers is that they can be easily deployed to the cloud, where flexible compute resources are available so you can maximize your application’s efficiency. As you might imagine, the major public cloud vendors are all eager for you to use their platforms to run your microservice-based apps. For more information, check out the resources from , , and .