Microservices, which are also referred to as microservice architecture is a software design approach that emphasizes creating an application as multiple services that are not tightly linked. The business problem is split into smaller units which are then implemented as services. Each unit has an assigned role to play which is separate from the roles played by the other units. When designing the units, isolation and autonomy are needed but communication between the different units is still required. The approaches that are used to communicate between the different units are REST and publish/subscribe.
In order to understand the difference between microservices and monolithic applications it is important to understand characteristics of applications developed using each approach. Applications developed using a monolithic approach will have the characteristics listed below.
• Applications are large with many developers working on them. This presents a challenge in managing the code in an IDE. Besides code management challenge there is a communication difficulty among developers. In the absence of effective communication, there is a difficulty in code duplication, application breaking and introducing new features.
• There is a lengthy release cycle due to huge management and testing effort required. Due to this long period frequent application delivery is impossible
• Implementing up and down scaling is very difficult.
• When a deployment fails, the entire application is not available.
• The technology that can be used to develop such applications is limited. For example, integrating JVM and non-JVM components becomes very difficult.
• Monolithic applications do not favor an agile approach that uses an iterative release cycle.
From the characteristics listed above it can be observed a monolithic approach is suitable on a small project that has a few developers. When there is an existing monolithic application, it may be unclear how to deal with it. One approach to migrate to microservices is to retain the monolithic application for core functionality and develop supporting services.
While discussing characteristics of monolithic applications, we identified several shortcomings that are mitigated by the microservices approach. The microservices architecture splits a monolithic application into smaller services that can be deployed independently on different hosts.
ach microservice has a specific business functionality and it is limited to this functionality. By dividing the application in this way each building block is managed by a few developers who are able to work in an agile approach. The only link between the building blocks is the APIs they expose.
Data management is implemented at the microservice level so each microservice owns its data. Data exchange between microservices happens through REST while data storage has multiple options such as relational databases, document databases or graph as data. Although, the use of microservices provides flexibility as to what technology can be used in application development it brings the challenge of data consistency.
From the discussion about microservices, the bullet points below summarize the key characteristics of microservice applications.
• There is a wide choice of technologies that can be used in application development
• Simplicity of the microservices enhances developer understanding thereby reducing possible code bugs and simplifies development and testing
• Service deployment is independent of other services in the applications
Earlier in the article, we noted the flexibility provided by microservices brings the challenge of data consistence. To resolve the data consistency problem, it is important to create clear boundaries. A microservice should only be allowed to connect to its own database therefore it should not have a direct connection to databases owned by other microservices. Application design needs to ensure every microservice clearly exposes an API with clear data model and data access rules. The use of those interfaces must be adhered to and when changes occur versioning is used for consistency.
A microservice architecture has the shortcoming of multiple deployment processes that increase server deployment complexity and Docker comes in to simplify deployment. The underlying technology in Docker is containerization where the microservice is packaged as an image that can be deployed. The image contains all the elements a microservice needs to function and it can be split into a service and a data container. Docker implements container isolation which results in an application consisting of Docker images. Although, the different containers are completely isolated the Linux kernel is shared, which optimizes performance due to reduced footprint as compared to traditional virtual machines. Deploying a higher microservice version is as simple as stopping one container and starting another and this will not affect the state of any other microservice.
When working with microservices the Docker features listed below are very handy:
• To implement scalability you just need to alter the number of container instances.
• Containers eliminate the complexity of the different technologies used. The process of starting a container is the same despite the technology
• Every service runs in complete isolation
• You are able to specify the CPU and memory allocation to a container
• There is image caching which improves the speed of creating new services
Docker solves the problem of deploying microservices created using different technologies. However, there is a new challenge of managing microservices spread out on different hosts. This is the problem of container management and orchestration, which is solved using Kubernetes, just one of the many tools available.
Kubernetes provides features that enable deployment, maintenance and application scaling. In Kubernetes a pod provides the basic deployment unit. A pod is made up of one or multiple containers that will always be on one host. Containers within a pod on the same host have a common IP address and they communicate through a localhost. A service provides a logical way to organize pods and specifies the rules to access the groups.
When working with a microservice architecture Kubernetes provides the features listed below:
• Automatically finding an appropriate host to place a container. Kubernetes will consider host workload and availability when determining the host that has the least workload. Even with an automated process of identifying a host you can still manually assign a host
• Kubernetes automates monitoring of resources such as memory, network, filesystem and CPU at cluster, container and pod.
• Kubernetes manages container lifecycle automatically. This happens through starting and stopping containers when workload changes. The number of containers is controlled by specifying metrics such as memory and CPU usage
In this article, we introduced the microservice and monolithic approaches to application development. We discussed the characteristics of applications developed using each approach. The challenges faced when developing applications using each approach were discussed. Solving the challenge of microservice deployment using Docker was discussed. Finally, we discussed solving the challenge of container management and orchestration using Kubernetes.