-
Book Overview & Buying
-
Table Of Contents
-
Feedback & Rating

Designing Microservices Platforms with NATS
By :

Let's try to understand the concepts of the microservice architecture with a practical example by decomposing a monolithic application into a set of microservices. We will be using a healthcare application for this purpose. The same application will be used throughout this book to demonstrate various concepts along the way.
Let's assume we are building an IT system for a hospital to increase the efficiency of the health services provided by the hospital to the community. In a typical hospital, many units exist, and each unit has one or more specific functionalities. Let's start with one particular unit, the outward patient department or OPD. In an OPD section, a few major functions are executed to provide services to people:
We'll start with one unit of the hospital and eventually build an entire healthcare system with microservices as we complete this book. Given that there are only four main functions, the IT team at the hospital has developed one web application that covers all these different functional units. The current design is a simple web application with four different web pages, each of which contains a form to update the details captured at each stage with a simple login. Anyone with an account in this system can view the details of all four pages.
Figure 1.5 – Simple web application for the OPD unit of a hospital
As depicted in the preceding diagram, the OPD web application is hosted in a web server (for example, Tomcat) and it uses a central database server to keep the data. This system works well, and users of this system are given a username and a password to access the system. Only authorized people can access the web application and it is hosted in a physical computing infrastructure inside the hospital.
Let's try to identify the challenges of this approach of building an application as a single unit or a monolith:
As a result of these challenges, the overall efficiency of the system becomes low and the opportunity to serve more patients with new services becomes harder. Instead, let's try to break this monolithic application down into small microservices.
More often than not, the microservice architecture demands a change in the organizational IT culture, as well as the software architecture and tools. Most organizations follow the waterfall approach to building software products. It follows a sequential method where each step in the sequence depends on the previous step. These steps include design, implementation, testing, deployment, and support. This sort of model won't work well with the microservice architecture, which requires a team that consists of people from these various internal groups and can act as a single unit to release each microservice in an agile manner.
Figure 1.6 – Waterfall development culture
The preceding diagram depicts a typical organizational IT culture where different teams with different expertise (center of excellence or CoE teams) work sequentially to develop and manage the life cycle of a software application. This model poses several challenges, such as the following:
This kind of organizational culture is not suitable for the highly demanding, innovation-driven enterprise platforms of today. Hence, it is necessary to reduce these boundaries and formulate truly agile teams before starting microservice-style development. Sometimes, it may be difficult to fully remove these boundaries at the beginning. But with time, the individuals and management will realize the advantages of the agile approach.
Figure 1.7 – Sprint-based agile development approach
The preceding diagram depicts an approach where the development of microservices is done as sprints. These focus on certain aspects of the software development life cycle within a defined time frame. One clear difference in this approach, compared to the waterfall approach, is that the team consists of people from different CoE teams, and a virtual team is formed for the sprint's duration. The responsibility of delivering the expected outcome is on their shoulders.
Let's focus on the application architecture where we identified the challenges with the monolithic approach, which was followed by the OPD web application. Instead of having several functions baked into one single application, the microservice architecture suggests building separate microservices for each function and making them communicate over the network whenever they need to interact with each other.
In the existing design, a common database is used to share data among different functions. In a microservice architecture, it makes sense for each microservice to have its data store and if there is a need to share data across services, services can use messaging or a separate microservice with that common data store instead of directly accessing a shared data store. We can decompose the application into separate microservices, as depicted in the following diagram:
Figure 1.8 – OPD application with microservices
If you find the preceding diagram too complicated, I suggest that you read this book until the end. By doing so, you will realize that this complexity comes with many advantages that outweigh the complexity in most cases. As we can see, the OPD web application is divided into a set of independent microservices that act as a cohesive unit to provide the necessary functionality to the consumers. The following is a list of major changes we made to the architecture of the application:
Let's explore these changes in a bit more detail so that we understand the practicalities of the approach.
In the book Domain-Driven Design by Eric Evans, he explained the approaches to follow when deciding on the boundaries for each microservice with many practical examples. At the same time, he reiterated the fact that this is not straightforward and that it takes some practice to achieve higher levels of efficiency. In the OPD example, this is somewhat straightforward since the existing application has certain levels of functional isolation at the presentation layer (web pages), though this is not reflected in the implementation. As depicted in the preceding diagram, we have identified six different microservices to implement for the OPD application. Each service has a clearly defined scope of functionality, as mentioned here:
Once the microservice boundaries have been defined, the implementation can follow an agile approach where one or more microservices are implemented at the same time, depending on the availability of the resources. Once the interfaces have been defined, teams do not need to wait until another service has been fully implemented. The resources can rotate among teams, depending on their availability. We will discuss additional details regarding the deployment architecture and its implementation details later in this book.
One of the main differences between the microservice-based approach and the monolithic approach we discussed in the previous sections is how data is handled. In the monolithic approach, there is a central data store (database) that stores the data related to each section of the OPD unit.
Whenever there is a need for data sharing, the application directly uses the database, and different functions access the same database (same table) without any control. This kind of approach can result in situations where data is corrupted due to an error in the implementation of a certain function and all the functions fail due to that. At the same time, finding the root cause would be hard since multiple components of the application access the same database or table. This kind of design will cause more problems when the applications have a higher load on the database, where all the parts of the application are affected due to the performance of one particular function.
Due to these reasons and many others, the microservice architecture suggests following an approach where each microservice has a data store. At the same time, if there is a need to share a common database across multiple microservices, it recommends having a separate microservice that wraps the database and provides controlled access. If there is a need to share data between microservices, that will be done through an inter-service communication mechanism via messages. We will discuss how to deploy these local data stores, along with microservices, later in this book.
In the monolithic approach, each function runs within the same application runtime (for example, JVM for Java) and whenever there is a need to communicate between functions, it uses an in-memory call such as a method call or function invocation. This is much more reliable and faster since everything happens within the same computer.
The microservice architecture follows a different approach for inter-service communication since each microservice runs on separate runtime environments. Also, these runtime environments may run on different networked computers. Many approaches can be used for inter-service communication, and we will explore all those options in Chapter 2, Why Is Messaging Important in a Microservice Architecture, of this book. For this initial introduction, we will use the message broker-based approach. We will also be using this throughout this book, so we will discuss it in more detail later in this book.
At the beginning of this chapter, we discussed the different networking topologies and the evolution of distributed systems. There, we identified that having a mesh topology can complicate the overall system architecture and make it harder to maintain the system. Hence, we suggest using a message broker-based approach for inter-service communication throughout this book. The advantages of this approach are as follows:
We will discuss the advantages of using message brokers for inter-service communication throughout this book.
As we discussed earlier in this chapter, the microservice style of application development involves making a lot of changes to the way engineers build applications. Traditional web applications are built in a manner where different sections of the application are developed as separate web pages and when the user needs to access a different section, the browser will load an entirely different web page, causing delays and a less optimal user experience.
Figure 1.9 – Multi-page OPD web application
As depicted in the preceding diagram, the user is accessing two pages of the web application. Each action triggers the following:
These traditional, multi-page applications can cause a significant performance impact to the user due to this multi-step process of loading a web page on the browser.
The concept of SPA addresses these issues and suggests an approach where the entire web application is designed as a single page that will be loaded to the browser at once. A page refresh won't occur when accessing different sections of the application, which will result in better performance and a better user experience.
Figure 1.10 – Single-page application with microservices
While there is only a single page for the presentation layer of the application, different microservices implemented at the backend provide the required data to be displayed in the web frontend. The advantage of having separate microservices with an SPA is that users with different privileges will only get access to the authorized details. They will also get access to those details in the shortest possible time since no additional data loading happens.
The preceding diagram only depicts a couple of microservices for the sake of simplicity. The real implementation would interact with all the different microservices we discussed in the previous section.
So far, we've discussed the approach that can be followed when decomposing a monolithic application into a microservice architecture at a very high level while providing a few details on certain aspects. We will be continuing with this topic throughout this book, which means you will get the opportunity to learn more along the way.
Change the font size
Change margin width
Change background colour