Microservice architecture is one of the most discussed software architecture trends at the moment, and it has forever changed the way enterprise applications are built. Rather than the slow, complex monolithic approach of the past, developers and companies everywhere are turning to microservices architecture to simplify and scale their structures. In fact, even companies like Amazon, Netflix, Spotify, and Uber have made the transition.
Whether you want to get started with Microservices or you’re just curious about the debate surrounding it, you’re in the right place. Today, I will walk you through everything you need to know about Microservices, from real-world examples to architecture patterns and more. We will cover the following:
- What is Microservices Architecture
- Benefits and drawbacks
- Microservices and Docker
- Tech stacks and architecture patterns
- Resource guide
Let’s get started!
There is no universal definition of the term microservices. The simplest definition of microservices, also called microservice architecture, is an architectural style that structures an application using loosely coupled services. These collections or modules can be independently developed, deployed, and maintained.
They operate at a much faster and reliable speed than the traditional complex, monolithic applications. Using microservice architectures, an organization of any size can evolve technology stacks tailored to their capabilities.
There are many tangible benefits to using microservices, which we will discuss later, but there is still some controversy over whether or not companies should switch from a monolithic to microservices architecture. Let’s examine the difference between the two to understand the debate.
The monolithic architecture is the traditional way of building and deploying applications. This structure is based around the concept of a single, indivisible unit, including the server side, client side, and database. All facets are unified and managed as a single unit and codebase. This means that any updates must be made to the same codebase, so the whole stack must be altered. As monolithic applications scale, they can become quite complex, so the overall development is generally longer.
A microservices architecture, on the other hand, breaks down that unit into independent ones that function as separate services. This means that every service has its own logic and codebase. They communicate with each other through APIs (Application Programming Interfaces).
So, which architecture should you choose? Let’s break it down.
If your company is a small team. This way you don’t have to deal with the complexity of deploying a microservice architecture.
If you want a quicker launch. Monolithic architecture requires less time to launch. This system will require more time later on to update your system, but the initial launch is quicker.
- If you want to develop a more scalable application. Scaling a microservices architecture is far easier. New capabilities and modules can be added with much ease and speed.
- If your company is larger or plans to grow. Using microservices is great for a company that plans to grow, as a microservices architecture is far more scalable and easier to customize over time.
There are a number of reasons why a microservices architecture is a better choice for your company. Let’s discuss the most notable benefits and then examine some of the drawbacks.
Large teams often have to work together on complex projects. With microservices, projects can be divided into smaller, independent units. This means that teams can act independently regarding domain logic, which minimizes the coordination and effort. On top of that, the teams responsible for each microservice can make their own technology decisions depending on their needs.
For example, the internal structure of each unit or container does not matter as long as the interface functions correctly. Therefore, any programming language can be used to write a microservice, so the responsible team can select the best language for their teammates.
Monolithic systems are hard to maintain. Many legacy systems are poorly structured, poorly tested, or depend upon outdated technologies. Luckily, microservices can work alongside legacy systems to improve the code and replace old parts of the system. Integration is easy and can solve many of the problems that make monolithic systems something of the past.
Microservice architectures create systems that remain maintainable in the long run since the various parts are replaceable. This means that a microservice can easily be rewritten without compromising the whole system. As long as the dependencies between microservices are managed appropriately, changes can easily be made to optimize team needs and performance.
Microservices are best for distributed teams. If you have teams around the world or various divisions, microservices grant the necessary freedoms and flexibility to work autonomously. Technical decisions can be made quickly that integrate with other services in a flash. Cross-functionality has never been easier.
The operation of a microservice system often requires more effort, since there are more deployable units that must each be deployed and monitored. Changes to interfaces must be implemented so that an independent deployment of individual microservices is still possible.
Since all microservices must be tested together, one microservice can block the test stage and prevent the deployment of the other microservices. There are more interfaces to test, and testing has to be independent for both sides of the interface.
Changes that affect multiple microservices can be more difficult to implement. In a microservice system, changes require several coordinated deployments.
Docker and Microservices are nearly synonymous. Microservices must be separately deployable, scalable independent units. But, what if you create multiple microservices for your application? Docker is a lightweight solution to deploying microservices. A microservice can be packed into a Docker image and isolated as a Docker container. This way, you can build an application that is independent of your host environment.
Instead of having a complete virtual machine of their own, Docker containers share the kernel of the operating system on the Docker host. The processes from the containers appear in the process table of the operating system on which the Docker containers are running.
To use Docker with microservices, you need to create Docker images via files named
Dockerfile. Dockerfiles are easy to write, so rolling out software can be easy. Take a look at an example of a Dockerfile for a Java microservice.
FROM openjdk:11.0.2-jre-slim COPY target/customer.jar . CMD /usr/bin/java -Xmx400m -Xms400m -jar customer.jar EXPOSE 8080
Want to learn more about Docker? Check out Educative’s course on the basics of Docker and Kubernetes
A typical microservice system contains multiple Docker containers. Coordinating a system of multiple Docker containers requires configurations for the virtual network. Containers must be able to find each other in order to communicate. The Docker Compose environment can contact another server via a link, offering a service discovery system.
Learn Microservice Architecture without scrubbing through videos or documentation. Educative's text-based courses are easy to skim and feature live coding environments - making learning quick and efficient.
It is one thing to understand how microarchitecture works and another to actually build and implement it. That’s why we want to focus on the various technologies available to you for an entire microservices system. Let’s walk through some different tech stacks, patterns, and designs for creating an executable microservice architecture.
It is advisable to divide your architecture into micro and macro architecture. The micro architecture involves all decisions made for each microservice. The macro architecture involves all decisions made at a global level that apply to all microservices.
It is possible to extend the concept of micro and macro architecture to technical decisions. Technical decisions can be made within the framework of macro or micro architecture. For example, take a look at the technical decisions to be made at the micro and macro levels for a database:
Micro: Each microservice can have its own instance of the database. If databases were defined at the micro architecture, a crash of one database will only lead to the crash of one microservice. This makes the whole app far more robust.
Macro: The database can also be defined as part of the macro architecture. Multiple microservices must not share a database schema.
A self-contained system (SCS) is a type of microservice architecture that specifies the elements of a macro architecture. This means they do not represent the whole system. Since an SCS is self-contained, it provides everything you need to implement one part of the domain logic, such as log data and a UI. SCSs also have an optional API.
For example, an SCS for a microservice payment would store information relevant to that payment as a bounded context. It would also implement the UI to show the payment history, and data about the customers would be replicated from other SCSs.
Think of these as a collection of best practices; SCSs provide precise rules based on established patterns, offering a point of reference for how to build a microservice architecture. All of these rules ensure that an SCS implements a domain, so an added feature only changes one SCS.
We can think of an SCS as a microservice architecture because it can be deployed independently and divide a system into independent web applications. In fact, one SCS can even be split into several microservices. They differ from microservices in three main ways: they are larger than microservices; they focus on loose coupling; they must have a UI.
You can learn more about SCSs here
Microservices can also be integrated with a web frontend. Dividing the frontend into different modules helps to solve some of the problems that come from treating it as a monolith. A modularized frontend is made up on separately deployable microservices. This can bring many benefits to your frontend.
For example, a modularized frontend can have independent domain logic, and a change in the domain can be implemented simply by modifying only one microservice. To combine separate frontend, they must be integrated, so an integration system is necessary.
This can be accomplished through links, where one frontend displays a link that another frontend reads and handles. This can also be accomplished through redirects, for example, how OAuth2 handles frontend integration. Redirects combine data transfer with frontend integration.
There are, however, a few exceptions when a frontend should be deployed as a monolith. For example, native mobile applications should be deployment monoliths or if there were a singular team responsible for frontend development.
Synchronous microservices make a request to other microservices while it processes requests and waits for results. Asynchronous communication protocols send messages that the recipients react to, but there is no direct response. A microservice could be defined as asynchronous if it does not make requests to other microservices while processing, or it makes requests but does not wait for results.
Asynchronous microservices offer several notable advantages to synchronous microservices and resolve many of the challenges of distributed systems. The logic required to handle microservice requests does not depend on results, making them far more independent.
Similarly, if a communication partner were to fail, it does not crash the whole system, offering overall resilience to your system. On top of that, the processing and delivery are almost always guaranteed.
Some common examples of technologies for asynchronous microservices are Kafka (a MOM commonly used for messaging), REST and Atom data format (for additional infrastructure).
Microservice platforms, such as PaaS and Docker scheduler, support the operation and communication of your microservices. These technologies enable communication between microservices for deployment, log analysis, and monitoring.
For example, these platforms support HTTP and REST with load balancing and service discovery. Limited operations support is needed for the implementation of microservices, so they can be quickly deployed and support multiple microservices.
Microservices platforms represent a simplification and solution to common issues. Some notable platforms are Kubernetes and Docker, which is very important for microservices operations. PaaS and Cloud Foundry are also useful but they are not as popular.
It’s important to note that migration to these platforms requires a change to the operation and installation of applications, which can make the use of a microservices platform a big and timely step. This is the main drawback of microservice platforms.
Now that you have a sense of what microservices architecture has to offer and what variations there are, you’re ready to get started with some hands-on learning. Take a look at our resource list below for more information on microservices.
Microservices Guide: a collection of articles tackle a variety of topics related to microservices
The Art of Monitoring in the Age of Microservices: a useful Q&A with author of “The Art of Monitoring” that covers monitoring strategies
Building Microservices:: the O’Reilly book on microservices
GitHub's Beginner Guide to Microservices: easy to navigate code repository for beginners
AWS Intro to Microservices: Amazon’s documentation and definition of microservice concepts
Looking for an online course you can really trust? We’ve got you covered with a two-part, all-you-need-to-know microservices series written by one of the experts in the field, Eberhard Wolff, a founding member of the Java Champions community.
Start with the basic principles of microservices to get down all the foundations necessary for deployment and implementation.
An Introduction to Microservice Principles and Concepts walks you through all the pros and cons of this exciting trend using real-world examples and migration strategies.
Then, you can move on to Microservice Architecture: Practical Implementation, one of the best courses for the nitty-gritty details of real world implementation.
This course walks you through real-world “recipes” and tech stacks. You’ll navigate the ins and outs of deployment and become a microservice pro by the end!
Both of these courses are based on Eberhard’s highly rated book on the same topic, so you know you’re getting top-notch instruction.
Get better equipped to tackle this growing trend!