Book Image

Hands-On Microservices with Spring Boot and Spring Cloud

By : Magnus Larsson
Book Image

Hands-On Microservices with Spring Boot and Spring Cloud

By: Magnus Larsson

Overview of this book

Microservices architecture allows developers to build and maintain applications with ease, and enterprises are rapidly adopting it to build software using Spring Boot as their default framework. With this book, you’ll learn how to efficiently build and deploy microservices using Spring Boot. This microservices book will take you through tried and tested approaches to building distributed systems and implementing microservices architecture in your organization. Starting with a set of simple cooperating microservices developed using Spring Boot, you’ll learn how you can add functionalities such as persistence, make your microservices reactive, and describe their APIs using Swagger/OpenAPI. As you advance, you’ll understand how to add different services from Spring Cloud to your microservice system. The book also demonstrates how to deploy your microservices using Kubernetes and manage them with Istio for improved security and traffic management. Finally, you’ll explore centralized log management using the EFK stack and monitor microservices using Prometheus and Grafana. By the end of this book, you’ll be able to build microservices that are scalable and robust using Spring Boot and Spring Cloud.
Table of Contents (26 chapters)
Title Page

Challenges with microservices

In the Challenges with autonomous software components section, we have already seen some of the challenges that autonomous software components can bring (and they all apply to microservices as well) as follows:

  • Many small components that use synchronous communication can cause a chain of failure problem, especially under high load.
  • Keeping the configuration up to date for many small components can be challenging.
  • It's hard to track a request that's being processed and involves many components, for example, when performing root cause analysis, where each component stores log events locally.
  • Analyzing the usage of hardware resources on a component level can be challenging as well.
  • Manual configuration and management of many small components can become costly and error-prone.

Another downside (but not always obvious initially) of decomposing an application into a group of autonomous components is that they form a distributed system. Distributed systems are known to be, by their nature, very hard to deal with. This has been known for many years (but in many cases neglected until proven differently). My favorite quote to establish this fact is from Peter Deutsch who, back in 1994, stated the following:

The 8 fallacies of distributed computingEssentially everyone, when they first build a distributed application, makes the following eight assumptions. All prove to be false in the long run and all cause big trouble and painful learning experiences:

  1. The network is reliable
  2. Latency is zero
  3. Bandwidth is infinite
  4. The network is secure
  5. Topology doesn't change
  6. There is one administrator
  7. Transport cost is zero
  8. The network is homogeneous
-- Peter Deutsch, 1994

Note: The eighth fallacy was actually added by James Gosling at a later date. For more details, please go to https://www.rgoarchitects.com/Files/fallacies.pdf.

In general, building microservices-based on these false assumptions leads to solutions that are prone to both temporary network glitches and problems that occur in other microservice instances. When the number of microservices in a system landscape increases, the likelihood of problems also goes up. A good rule of thumb is to design your microservice architecture based on the assumption that there is always something going wrong in the system landscape. The microservice architecture needs to be designed to handle this, in terms of detecting problems and restarting failed components but also on the client-side so that requests are not sent to failed microservice instances. When problems are corrected, requests to the previously failing microservice should be resumed; that is, microservice clients need to be resilient. All of these need, of course, to be fully automated. With a large number of microservices, it is not feasible for operators to handle this manually!

The scope of this is large, but we will limit ourselves for now and move on to study design patterns for microservices.