Book Image

Designing Microservices Platforms with NATS

By : Chanaka Fernando
5 (1)
Book Image

Designing Microservices Platforms with NATS

5 (1)
By: Chanaka Fernando

Overview of this book

Building a scalable microservices platform that caters to business demands is critical to the success of that platform. In a microservices architecture, inter-service communication becomes a bottleneck when the platform scales. This book provides a reference architecture along with a practical example of how to implement it for building microservices-based platforms with NATS as the messaging backbone for inter-service communication. In Designing Microservices Platforms with NATS, you’ll learn how to build a scalable and manageable microservices platform with NATS. The book starts by introducing concepts relating to microservices architecture, inter-service communication, messaging backbones, and the basics of NATS messaging. You’ll be introduced to a reference architecture that uses these concepts to build a scalable microservices platform and guided through its implementation. Later, the book touches on important aspects of platform securing and monitoring with the help of the reference implementation. Finally, the book concludes with a chapter on best practices to follow when integrating with existing platforms and the future direction of microservices architecture and NATS messaging as a whole. By the end of this microservices book, you’ll have developed the skills to design and implement microservices platforms with NATS.
Table of Contents (15 chapters)
1
Section 1: The Basics of Microservices Architecture and NATS
5
Section 2: Building Microservices with NATS
11
Section 3: Best Practices and Future Developments

Characteristics of the microservice architecture

In this section, we will discuss the different characteristics of a typical microservice architecture. Given the fact that the microservice architecture is still an evolving architecture, don't be surprised if the characteristics you see here are slightly different than what you have seen already. That is how the evolving architectures work. However, the underlying concepts and reasons would be the same in most cases:

  • Componentization via services
  • Each service has a scope identified based on business functions
  • Decentralized governance
  • Decentralized data management
  • Smart endpoints and dumb pipes
  • Infrastructure automation
  • Container-based deployments
  • Designing for failure
  • Agile development approach
  • Evolving architecture

Let's discuss these characteristics in detail.

Componentization via services

Breaking down large monolithic applications into separate services was one of the successful features of SOA, and it allowed engineers to build modular software systems with flexibility. The same concept is carried forward by the microservice architecture with much more focus. Instead of stopping at the modularity of the application, it urges for the autonomy of these services by introducing concepts such as domain-driven design, decentralized governance, and data management, all of which we will discuss in the next section.

This allows the application to be more robust. Here, the failure of one component (service) won't necessarily shut down the entire application since these components are deployed and managed independently. At the same time, adding new features to one particular component is much easier since it does not require deploying the entire application and testing every bit of its functionality.

Business domain-driven scope for each service

The modular architecture is not something that was introduced with microservices. Instead, it has been the way engineers build complex and distributed systems. The challenge is with scoping or sizing these components. There are no definitions or restrictions regarding the component's sizes in the architectures that came before microservices. But microservices specifically focus on the scope and the size of each service.

The amount of work that is done by one microservice should be small enough so that it can be built, deployed, and managed independently. This is an area where most people struggle while adopting microservices since they think it is something that they should do right the first time. But the reality is that the more you work on the project, the better you become at defining the scope for a given microservice.

Decentralized governance

Instead of having one team governing and defining the language, tools, and libraries to use, microservices allow individual teams to select the best tool that is suitable for their scope or use case. This is often called the polyglot model of programming, where different microservices teams use different programming languages, databases, and libraries for their respective service. It does not stop there, though – it even allows each team to have its own software development life cycles and release models so that they don't have to wait until someone outside the team gives them approval. This does not necessarily mean that these teams do not engage with the experienced architects and tech leads in the organization. They will become a part of the team during the relevant sprints and work with these teams as a team member rather than an external stakeholder.

Decentralized data management

Sometimes, people tend to think that the microservice style is only suitable for stateless applications and they avoid the question of data management. But in the real world, most applications need to store data in persistent storage, and managing this data is a key aspect of application design. In monolithic applications, everything is stored in a single database in most cases, and sharing data across components happens through in-memory function calls or by sharing the same database or tables. This approach is not suitable for the microservice architecture and it poses many challenges, such as the following:

  • A failure in one component handling data can cause the entire application to fail.
  • Identifying the root cause of the failure would be hard.

The microservice architecture suggests the approach of having databases specific to each microservice so that it can keep the state of the microservice. In a situation where microservices need to share data between them, create a separate microservice for common data access and use that service to access the common database. This approach solves the two issues mentioned previously.

Smart endpoints and dumb pipes

One of the key differences between the monolithic architecture and the microservice architecture is the way each component (or service) communicates with the other. In a monolith, the communication happens through in-memory function calls and developers can implement any sort of interconnections between these components within the program, without worrying about failures and complexity. But in a microservice architecture, this communication happens over the network, and engineers do not have the same freedom as in monolithic design.

Given the nature of the microservice approach, the number of services can grow rapidly from tens to hundreds to thousands in no time. This means that going with a mesh topology for inter-service communication can make the overall architecture super complex. Hence, it suggests using the concept of smart endpoints and dumb pipes, where a centralized message broker is used to communicate across microservices. Each microservice would be smart enough to communicate with any other service related to it by only contacting the central message broker; it does not need to be aware of the existence of other services. This decouples the sender and the receiver and simplifies the architecture significantly. We will discuss this topic in greater detail later in this book.

Infrastructure automation

The autonomy provided by the architecture becomes a reality by automating the infrastructure that hosts the microservices. This allows the teams to rapidly innovate and release products to production with a minimum impact on the application. With the increased popularity of Infrastructure as a Service (IaaS) providers, deploying services has become much easier than ever before. Code development, review testing, and deployment can be automated through the continuous integration/continuous deployment (CI/CD) pipelines with the tools available today.

Container-based deployments

The adoption of containers as a mechanism to package software as independently deployable units provided the impetus that was needed for microservices. The improved resource utilization provided by the containers against the virtual machines made the concept of decomposing a monolithic application into multiple services a reality. This allowed these services to run in the same infrastructure while providing the advantages offered by the microservices.

The microservice architecture created many small services that required a mechanism to run these services without needing extra computing resources. The approach of virtual machines was not good enough to build efficient microservice-based platforms. Containers provided the required level of process isolation and resource utilization for microservices. The microservice architecture would have not been so successful if there were no containers.

Design for failure

Once the all-in-one monolithic application had been decomposed into separate microservices and deployed into separate runtimes, the major setback was communication over the network and the inevitable nature of the distributed systems, which is components failing. With the levels of autonomy we see in the microservices teams, there is a higher chance of failure.

The microservice architecture does not try to avoid this. Instead, it accepts this inevitable fact and designs the architecture for failure. This allows the application to be more robust and ready for failure rather than crashing when something goes wrong. Each microservice should handle failures within itself and common failure handling concepts such as retry, suspension, and circuit breaking need to be implemented at each microservice level.

Agile development

The microservice architecture demands changes in not only the software architecture but also the organizational culture. The traditional software development models (such as the waterfall method) do not go well with the microservice style of development. This is because the microservice architecture demands small teams and frequent releases of software rather than spending months on software delivery with many different layers and bureaucracy. Instead, the microservice architecture works with a more product-focused approach, where each team consists of people with multiple disciplines that are required for a given phase of the product release.

Evolving architecture

The concepts or characteristics we've discussed so far are by no means set in stone for a successful microservice implementation. These concepts will evolve with time and people will identify new problems, as well as come up with better approaches, to solve some of the problems that the microservice architecture tries to solve. Hence, it is important to understand that the technology landscape is an ever-evolving domain and that the microservice architecture is no exception.