Book Image

Embracing Microservices Design

By : Ovais Mehboob Ahmed Khan, Nabil Siddiqui, Timothy Oleson
Book Image

Embracing Microservices Design

By: Ovais Mehboob Ahmed Khan, Nabil Siddiqui, Timothy Oleson

Overview of this book

Microservices have been widely adopted for designing distributed enterprise apps that are flexible, robust, and fine-grained into services that are independent of each other. There has been a paradigm shift where organizations are now either building new apps on microservices or transforming existing monolithic apps into microservices-based architecture. This book explores the importance of anti-patterns and the need to address flaws in them with alternative practices and patterns. You'll identify common mistakes caused by a lack of understanding when implementing microservices and cover topics such as organizational readiness to adopt microservices, domain-driven design, and resiliency and scalability of microservices. The book further demonstrates the anti-patterns involved in re-platforming brownfield apps and designing distributed data architecture. You’ll also focus on how to avoid communication and deployment pitfalls and understand cross-cutting concerns such as logging, monitoring, and security. Finally, you’ll explore testing pitfalls and establish a framework to address isolation, autonomy, and standardization. By the end of this book, you'll have understood critical mistakes to avoid while building microservices and the right practices to adopt early in the product life cycle to ensure the success of a microservices initiative.
Table of Contents (16 chapters)
1
Section 1: Overview of Microservices, Design, and Architecture Pitfalls
6
Section 2: Overview of Data Design Pitfalls, Communication, and Cross-Cutting Concerns
10
Section 3: Testing Pitfalls and Evaluating Microservices Architecture

Defining core priorities for a business

Since the microservice architecture is gaining momentum, more and more organizations have started thinking about adopting a new way of building applications. These organizations are setting themselves up for a journey. Startups are challenged with limited resources and deciding what to build in-house and what to outsource. Large organizations are looking to adopt new ways to deliver value faster to their end customers. They are building new applications and also looking to transform their legacy applications into microservices to gain the benefits of being more nimble and agile. As they progress through their journey, they will need to make decisions and deal with lots of trade-offs.

To start, it's important to outline the charter based on your business priorities. If the focus is on building new features and increasing team velocity, then innovation should be prioritized over reliability and efficiency. The following diagram depicts different dimensions that need to be prioritized based on business priorities:

Figure 1.2 – Different dimensions of business priorities

Figure 1.2 – Different dimensions of business priorities

If providing a reliable service to your customer is your primary goal, then reliability should be prioritized over innovation and efficiency. If efficiency is more important, then you must focus on making the right changes to become an efficient organization. By doing so, innovation and reliability may need to be addressed later in the value chain. For example, being more efficient enables experimentation at a low cost, which allows teams to try out new things more often.

Technology leaders need to make sure that their team is ready, and they must be aware of cultural change, new ways of communication, learning new tools and technologies, autonomy in making decisions about their service domains, and be open for collaboration to ensure governance. Technology leaders should bring clarity by defining and communicating the right architecture to the teams.

As an architect, you need to make sure that you are capturing all the decisions that are mutually agreed upon, their benefits, and their trade-offs. You are also responsible for documenting and communicating the implications of these decisions. Documenting these decisions will help you look back and find reasons for making those decisions. This will allow you to make more informed decisions in the future. Identifying good candidates for microservices and modeling them around business capabilities is crucial. You should start with services that are not critical to the business and evolve your architecture incrementally.

Building a new application or transforming a legacy application into microservices is a crucial decision for an organization. It's highly unlikely that you should lay out a detailed plan for such initiatives, but the new services should be designed in a way that they should cater to the current and emerging business requirements. However, understanding the current system can help in identifying areas that can deliver the most impact. Another important aspect is observing the usage patterns of different parts of the application to understand how clients and different parts of the application are interacting with each other. For many organizations, modernizing legacy applications and adding new features to address customer needs are competing priorities. There are mainly three approaches that are adopted as teams start converting those applications into microservices:

  • Replacing existing functionality with new microservices that are being built using new tools and frameworks to avoid any technical debt. This requires a huge investment upfront to fully understand the legacy system. It's usually recommended for small legacy systems or a module in a large legacy application that offers limited functionality.
  • Extracting an existing functionality that exists in different modules as microservices. This approach is recommended for legacy applications that are well maintained and structured throughout their life cycle.
  • As an application continues to grow, it's highly unlikely that the initial design principles are followed during its lifespan. In such cases, a balanced approach should be adopted to allow teams to refactor old applications. This helps them clearly define module boundaries, which can later serve as a means of extracting code from microservices.

The microservice architecture is an implementation of distributed computing, where different microservices make use of parallel compute units to achieve resiliency and scale. Over the last decade, cloud providers have been enabling organizations to reap the benefits of distributed computing by eliminating the need for heavy investment upfront. High-performing organizations are focusing on embracing cloud-native development to accelerate their microservices journey.

Scalability and availability are no longer an afterthought for organizations for building enterprise-grade applications. Cloud-native technologies are playing an instrumental role in enabling organizations to incorporate these characteristics while spanning different clouds environments (public, private, or hybrid). Some of the technologies that are contributing to this development are DevOps, microservices, service meshes, and Infrastructure as Code (IaC).

Cloud-native applications are built to make use of cloud services to provide a consistent experience for developing and operationalizing different environments. This approach has allowed organizations to consume Platform-as-a-Service (PaaS) compute infrastructure as a utility and outsource the infrastructure management to cloud vendors. These services are responsible for provisioning the underlying infrastructure, its availability, scalability, and other value-added services. One huge drawback of directly using cloud services without any intermediate abstraction (in the form of a library or framework) is that it makes it harder for organizations to move to different solutions or different cloud providers. Dapr, which stands for Distributed Application Runtime, uses a sidecar pattern to provide such abstraction between microservices and cloud services. Dapr will be covered in detail in Chapter 3, Microservices Architecture Pitfalls.

The cloud-native approach focuses on adopting four major practices:

  • DevOps is the union of people, processes, and products to enable continuous delivery of value to our end users (as defined by Donovan Brown).
  • Continuous delivery is a software development discipline where you build software in such a way that the software can be released to production at any time (as defined by Martin Fowler).
  • Microservices is an architecture style that allows applications to be built as a set of loosely coupled, fine-grained services. These services have logical and physical separation, and they communicate with each other over a network to deliver a business outcome.
  • Containers or containerization is a new way of packaging and deploying applications. The container technology enables packaging applications and their dependencies together to minimize discrepancies across environments.

Software methodology plays an important role in building an application that follows the best practices to deliver software. Twelve-factor app is a widely adopted methodology for building microservices. Let's look closely at the various factors that are essential to understand before starting this journey.