Hands-On Microservices - Monitoring and Testing

By Dinesh Rajput
  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Software Architecture Patterns

About this book

Microservices are the latest "right" way of developing web applications. Microservices architecture has been gaining momentum over the past few years, but once you've started down the microservices path, you need to test and optimize the services. This book focuses on exploring various testing, monitoring, and optimization techniques for microservices.

The book starts with the evolution of software architecture style, from monolithic to virtualized, to microservices architecture. Then you will explore methods to deploy microservices and various implementation patterns. With the help of a real-world example, you will understand how external APIs help product developers to focus on core competencies.

After that, you will learn testing techniques, such as Unit Testing, Integration Testing, Functional Testing, and Load Testing. Next, you will explore performance testing tools, such as JMeter, and Gatling. Then, we deep dive into monitoring techniques and learn performance benchmarking of the various architectural components. For this, you will explore monitoring tools such as Appdynamics, Dynatrace, AWS CloudWatch, and Nagios.

Finally, you will learn to identify, address, and report various performance issues related to microservices.

Publication date:
October 2018
Publisher
Packt
Pages
160
ISBN
9781789133608

 

Chapter 1. Software Architecture Patterns

Nowadays, software is not only used for providing services but is also used to develop business. The best-performing software allows a business to grow. Today's application software shouldn't focus on a specific device such as a computer; instead, it should be able to support any platform. As architects, we have to focus on the design of the software application at the time of development. It must be scalable, either vertically or horizontally, and it should be able to cope with millions, or even billions, of requests per second.

In this chapter, we will discuss application architecture patterns, such as the conventional monolithic architecture pattern and the microservice architecture pattern. We will look at where the concept of conventional monolithic architecture comes from and what advantages it has relating to the software development life cycle. We will also explain the limitations of the monolithic architecture, which leads to the need to build loosely-coupled systems, otherwise known as the microservice architecture.

By the end of this chapter, you will be able to understand the traditional approach to building software solutions by adopting a monolithic architecture pattern. You will read about the evolution of the architecture pattern from monolithic to microservice-related. We will also provide a detailed explanation of the microservice architecture and information about how it can be used in this chapter.

This chapter will cover the following topics:

  • The monolithic architecture pattern:
    • Example
    • Benefits
    • Limitations
  • The microservice architecture pattern:
    • Example
    • Benefits
    • Limitations
  • Service-Oriented Architecture (SOA)
  • SOA versus microservice architecture

Let’s get started and look at these topics in detail.

 

The monolithic architecture pattern


When I started my job at Paytm, an e-commerce and payment gateway company in India, it was a startup company. We began with monolithic application architecture because there was only two of us there at the time. Many startups begin application development by following monolithic application architecture due to the small size of their team. Monolithic architecture doesn't give you big operational overhead costs, and they often have just one massive codebase.

A monolithic application is a single artifact that includes the interfaces of all layers. For example, a database might have several tables and DAO classes, a client-side UI that includes HTML pages and JavaScript, and a server-side application. This server-side application has to handle HTTP requests, process business logic using service classes, retrieve and update data from the database, exchange messages with other systems, and return responses in an HTML/JSON/XML format. A monolithic application often has a massive codebase which includes all of the aforementioned. As a developer, if you want to make any changes to this massive codebase, you have to build and deploy another updated version of the server-side application.

In a server-side application, you have to focus on development to provide support to a variety of different clients, such as desktop browsers, mobile browsers, and native mobile applications, including Android and iOS. A monolithic application must, therefore, have a complete code in order to support a variety of different clients. Let's discuss an example of a monolithic architecture pattern.

Monolithic application example

Suppose we are working on an e-commerce application that provides an online bookshop portal. It takes orders from customers, verifies the availability of the ordered book, places an order, and ships the ordered book to the customer. To build this application, we have to create several modules.

 

 

These include a Shop Front UI module, which provides a user interface to customers, and backend services, such as an Account Service, a Book Service, an Order Service, a Shipping Service, and so on. These services have various responsibilities, including verifying the customer, checking the availability of books, placing an order, and shipping the order.

All of these modules will be deployed as a single monolithic application either as a WAR file or JAR file. A Java web application as a WAR file runs on a web container such as Tomcat. This web application serves all HTTP requests that come from various clients, such as desktop or mobile browsers. The request comes first to Apache or Nginx and then to Tomcat.

You can also create multiple instances of this monolithic application to handle millions or billions of requests, or include a load balancer to scale and improve availability.

The following diagram illustrates the architectural design of a monolithic application:

As you can see in the preceding diagram, all modules of this traditional web application, such as Shop Front UI, Account Service, Order Service, Book Service, and Shipping Service, are single artifacts in the Tomcat container. This monolithic application has a massive codebase that includes all modules. If you introduce new modules to this application, you have to make changes to the existing code and then deploy the artifact with a different code to the Tomcat server.

 

Server-side application developers can include the following components in the architecture design:

  • Presentation: This layer handles HTTP requests and responds with HTML, JSON, or XML
  • Business logic: This is the business logic written into services such as the Account Service or Customer Service
  • Data access: These objects are responsible for accessing the database for business logic
  • Application integration: This component is responsible for integrating the application with other external services via messaging or the REST API

In monolithic application architecture, we place such components as a single artifact in the server-side application. This application architecture means that a new team member can be introduced to the application easily due to the close nature of the team. However, when you have to change the application due to scalability or availability requirements, you have to run multiple copies of the application on multiple machines.

Monolithic application architecture can be made logically modular by dividing it into different layers according to the types of components. All modules and different layers are packaged and deployed as a single artifact monolithic application. Let's now move on and look at the benefits of monolithic application architecture.

Benefits of monolithic application architecture

The monolithic solution has the following benefits:

  • Simple to develop: Monolithic applications are very simple to develop because current development tools and IDEs support the development of monolithic applications
  • Simple to test: As we have already discussed, monolithic applications have all of their modules in a single artifact, so you can easily carry out end-to-end testing by simply running the application either manually or with Selenium
  • Simple to deploy: A monolithic application is a single artifact, so you can easily deploy it to the server as a WAR file
  • Simple to scale: You can easily achieve scaling by copying the single artifact of the application to multiple running machines and setting up a load balancer behind the monolithic application

 

 

As you can see, monolithic applications have numerous benefits. They also have several disadvantages, which we will discuss shortly, but let's first have a look at the situations in which monolithic applications are useful.

When to use monolithic architecture

Monolithic architecture can be used in the following situations:

  • In the foundation stage of projects – most of the time, big, successful applications start with monolithic application architecture
  • When building an unproven product or proof of concept
  • When your development team is less experienced

Despite the benefits of monolithic application architecture, there are also a few disadvantages.

Limitations of monolithic application architecture

Monolithic application architecture can sometimes have the following disadvantages:

  • A monolithic application has a large codebase, which can intimidate developers, especially those who are new to the team. The application can be difficult to understand and modify. As a result, development is typically quite slow.
  • The application is large and complex, which makes it difficult to fully understand and make changes quickly and correctly.
  • The impact of a change is usually not very well understood, which leads to carrying out extensive, additional manual testing.
  • The architecture can be difficult to scale when different modules have conflicting resource requirements.
  • Monolithic applications aren't very reliable; a bug in any module can bring down the whole application.
  • They are not very adept at adopting new technologies. Since changes in frameworks or languages will affect an entire application, it is extremely expensive both time-wise and cost-wise.

Let’s now discuss which software development processes are better with monolithic architecture.

Software development processes with monolithic architecture

For a monolithic application, traditional software development processes, such as waterfall processes, are most suitable. This is because a monolithic application usually has large teams working on a single deployment artifact.

As we have discussed, a monolithic application is a single artifact, built as a single unit. This means that it handles the HTTP requests and executes business logic using DAOs to retrieve data from the underlying database at the server-side. However, with a monolithic application, if any changes are made to the application, another version of the entire application will need to be built. Fortunately, this is where the microservice architecture pattern can come to the rescue.

 

Microservice architecture pattern


In the previous section, we discussed the monolithic application architecture – in other words, the collection of all modules of an application as a single artifact. There is another architecture pattern that structures an application so that all modules of that application are loosely-coupled, share their services, and are independently deployable. In this approach, each service must be focused on a set of narrowly-related functions and each service runs independently and as a unique process. An application might consist of services, such as the Order Service, the Account Service, and so on. This approach is known as microservice architecture.

Microservice architecture refers to a method of software development in which a large software application is divided into several independently deployable services. These services are small, modular, and follow the single responsibility principle of software development. Each service is treated as a unique process that communicates with each other through a well-defined mechanism. We will discuss this further in Chapter 4, Inter-Service Communication.

In microservice architecture, all services communicate with each other either synchronously, using HTTP or REST, or asynchronously, using AMQP or Kafka. Each service contains its own database. The basic idea behind microservice architecture is to split up your monolithic application into a set of smaller, interconnected services.

 

 

A microservice architecture pattern separates concerns on a process level. All processes in this architecture are loosely coupled with each other. They communicate using predefined rules to achieve a business goal. So, let's move on and look at an example of a microservice-based application.

Microservice application example

We discussed a monolithic application in the previous section, in the form of an online book shop. In this section, we are going to discuss the same example using microservice architecture. The online bookshop application has four modules; Account Service, Book Inventory Service, Order Service, and Shipping Service. This application also has a user interface application, the Shop Front UI web application, which serves user requests and sends responses.

The following diagram illustrates the architecture of the application, which consists of a set of services:

As you can see, we have divided the earlier monolithic bookshop application into several independent services: Account Service, Book Service, Order Service, and Shipping Service. This is amicroservices architectural style; according to this approach, we can develop a single application as a suite of small services.

Each service is built around a business capability and is independently deployable into the server. For example, the Account Service manages the customer’s account and has its own database, Account DB. Similarly, the Book Service manages the inventory of the books and has the database Inventory DB. The Order Service manages the customer’s orders using a separate database, Order DB. Finally, the Shipping Service manages shipping orders using the Shipping DB. Each module has its own dependency without depending on other services. This means that we can choose different technologies as well as develop separate services.

The server-side application must handle requests coming from various clients, such as desktop or mobile browsers and native mobile apps. The Shop Front UI web application handles the HTTP requests that come from browsers. Some APIs are exposed to the native mobile app, so the app doesn't call these APIs directly – instead, the app communicates through an intermediary known as an API Gateway. The API Gateway is responsible for handling these requests using load balancing. The API Gateway also offers caching, access control, and API monitoring.

We'll discuss the benefits of the microservice architecture pattern in the following section.

Benefits of microservice application architecture

The following are some of the benefits of the microservice architecture pattern:

  • Easy to maintain: It is very easy for the developer to understand; this way, you can start development faster, which in turn makes it more productive
  • Easy to scale: You can easily scale individual components
  • Technology diversity: Microservices allow you to mix libraries, frameworks, data storage, and languages
  • Fault isolation: Component failure should not bring the whole system down
  • Better support: The architecture is suitable for smaller, parallel teams
  • Independent deployment: We can easily deploy each microservice independently without impacting other microservices in the architecture

 Microservice-based architecture also has a few disadvantages, however, and we'll take a look at them in the following section.

 

 

Disadvantages of the microservice architecture pattern

Microservices provide several benefits, but there are also some challenges relating to microservice architecture when developing an enterprise application. These include the following:

  • It is sometimes difficult to achieve strong consistency across services and transactions.
    • Atomicity, Consistency, Isolation, Durability (ACID) transactions do not span multiple processes. ACID is a set of properties of database transactions intended to guarantee validity, even in the event of errors, power failures, and so on. This can be counteracted, however, using eventual consistency, which helps to manage transactions in a microservice application.
  • A distributed system often:
    • Is harder to debug or trace
    • Has a greater need for end-to-end testing
    • Requires you to expect, test for, and handle the failure of any process
    • Has more components to maintain, which leads to issues such as redundancy or High Availability (HA)
  • It typically requires a cultural change with regards to DevOps, such as how applications are developed and deployed, and the cooperation of Development and Operation teams

In light of its disadvantages, in the next section, we will discuss when to use microservice architecture for your project.

When to use microservice architecture

One of the challenges related to microservice architecture is deciding when to use it. The following scenarios are examples of when it is a good idea to start using microservice architecture in your project:

  • New project development: Microservice architecture is more suitable when developing the first version of an application. You can plan your project and its associated modules from an initial level, whereas it can be challenging to convert an old or legacy project into a microservice-based application.
  • Separating concerns in the business application: This architecture provides a better level of separation of concerns as the Spring framework provides separation of concerns at the level of the application’s components.
  • Development of a cloud-native application: This architecture provides cloud-native patterns and supports distributed application development. We can create numerous independent services which can be deployed to a different platform on a different network, as can be done in the cloud.
  • Quick development of independent service delivery: Microservice architecture allows us to develop a business application quickly by dividing it into the independent delivery of individual parts within a larger, integrated system.
  • Efficient modules: In a business application, there are some modules that are very important for a business, and these modules must be developed in extremely efficient ways. Microservice architecture allows you to use better technologies for these modules to improve their efficiency.
  • Alongside a fast-growing product or team: If you start with microservice architecture, it provides your team with the flexibility to develop a product quickly. It also provides scalability to your application from the beginning.

Essentially, microservice-based application development better follows an agile software development process, because different, small teams work on separate modules of the application. The teams are therefore able to release services with continuous delivery. Now, let's move on to another type of software application architecture.

 

Service-oriented architecture (SOA)


SOA is another application architectural style. In SOA, architecture services are provided to other services and to vendor components using a communication protocol over a network. These services are discrete units of functionalities that can be accessed remotely. The following diagram shows an SOA in action:

As you can see in the preceding diagram, there are two main layers of the SOA: a service consumer layer and a service provider layer. The service consumer layer is the point at which all the consumers, such as human consumers and other service consumers, interact with the SOA. The provider layer is the point where all services are defined within the SOA.

In the preceding diagram, the Enterprise Service Bus (ESB) provides communication by a common communication protocol, or communication bus, which has connections between the consumers and providers. In SOA architecture, database storage is shared between all services.

SOA has more dependent ESBs. The ESBs implement a communication system between mutually interacting software applications with microservices. It also uses faster messaging mechanisms.

Let's now move on and take a look at the differences between SOA and microservice architecture.

 

SOA versus microservice architecture


The following table lists some of the differences between SOA and microservice architecture:

Service-oriented Architecture (SOA)

Microservice architecture

Focuses on imperative programming

Focuses on a responsive actor programming style

Its models tend to have an outsized relational database

Microservices frequently use NoSQL or micro-SQL databases (which can be connected to conventional databases)

In SOA, ESB implements communication between mutually-interacting software

In microservices, independent processes communicate with each other using language-agnostic APIs

It is easier to deploy new versions of services frequently, or scale a service independently

Services can operate and be deployed independently of other services

SOA has ESB, which could be a single point of failure that impacts the entire application

Microservice architecture has a much better fault-tolerance system

Data storage is shared between services

Each service has its own data storage

 

Summary


In this chapter, we discussed different software application architecture patterns, including monolithic, microservice, and SOAs. Monolithic architecture means building an application that includes all of its modules as a single artifact. It is better for simple and lightweight applications,

but it has various drawbacks, such as its large codebase, which can become difficult to manage. Even after making only a small change to the codebase, a new version of the complete application codebase must be built and deployed to the server. To resolve the problems of monolithic architecture, microservice architecture can be used.

Microservice-based architecture resolves many of the problems of monolithic architecture. This architecture pattern decomposes a monolithic application into several different and independent processes. These processes are known as microservices. A microservice architecture pattern is the better choice for complex, evolving applications. In essence, this architecture pattern handles a complex system better than monolithic architecture.

In Chapter 2, Anatomy of Microservice Decomposition Services, we'll look at how to decompose services in microservice architecture.

About the Author

  • Dinesh Rajput

    Dinesh Rajput is a founder of Dineshonjava (dot) com, a blog for Spring and Java techies. He is a Spring enthusiast and a Pivotal Certified Spring Professional. He has written two bestselling books, Spring 5 Design Patterns and Mastering Spring Boot 2.0. Mastering Spring Boot 2.0 is the Amazon #1 best-selling book on Java. He has more than 10 years of experience with various aspects of Spring and cloud-native development, such as REST APIs and microservice architecture. He is currently working as an architect at a leading company. He has worked as a tech lead at Bennett, Coleman & Co. Ltd, and Paytm. He has a master's degree in computer engineering from JSS Academy of Technical Education, Noida, and lives in Noida with his family.

    Browse publications by this author
Book Title
Unlock this full book FREE 10 day trial
Start Free Trial