Chapter 1. Preliminaries

This chapter provides an overview of the concept of a microservice. The first section defines microservices. The second section answers the question “Why microservices?” Finally, the chapter ends by discussing the challenges associated with microservices.

1.1 Overview of Microservice

The focus of this book is microservices—an approach to the modularization of software. Modularization in itself is nothing new. For quite some time, large systems have been divided into small modules to facilitate the implementation, understanding, and further development of the software.

Microservices are a new approach to modularization. However, the term “micro-service” is not really well defined, so the chapter starts with a definition of the term and describes how microservices are different from the usual deployment monoliths.

Microservice: Preliminary Definition

The new aspect is that microservices use modules that run as distinct processes. This approach is based on the philosophy of UNIX, which can be reduced to three aspects:

• One program should fulfill only one task, but it should perform this task really well.

• Programs should be able to work together.

• A universal interface should be used. In UNIX this is provided by text streams.

The term microservice is not firmly defined. Chapter 3, “What Are Microservices,” provides a more detailed definition. However, the following criteria can serve as a first approximation:

• Microservices are a modularization concept. Their purpose is to divide large software systems into smaller parts. Thus they influence the organization and development of software systems.

• Microservices can be deployed independently of each other. Changes to one microservice can be taken into production independently of changes to other microservices.

• Microservices can be implemented in different technologies. There is no restriction on the programming language or the platform for each microservice.

• Microservices possess their own data storage: a private database or a completely separate schema in a shared database.

• Microservices can bring their own support services along, for example a search engine or a specific database. Of course, there is a common platform for all microservices—for example virtual machines.

• Microservices are self-contained processes or virtual machines, e.g., to bring the supporting services along.

• Microservices have to communicate via the network. To do so microservices use protocols that support loose coupling, such as REST or messaging.

Deployment Monoliths

Microservices are the opposite of deployment monoliths. A deployment monolith is a large software system that can only be deployed in one piece. It has to pass, in its entirety, through all phases of the continuous delivery pipeline, such as development, the test stages, and release. Due to the size of deployment monoliths, these processes take longer than for smaller systems. This reduces flexibility and increases process costs. Internally, deployment monoliths can have a modular structure; however, all modules have to be brought into production simultaneously.

1.2 Why Microservices?

Microservices enable software to be divided into modules, making it easier to change the software.

As illustrated in Figure 1.1, microservices offer a number of important advantages.

Image

Figure 1.1 Advantages of Microservices

Strong Modularization

Microservices offer a strong modularization concept. Whenever a system is built from different software components, such as Ruby GEMs, Java JARs, .NET assemblies or Node.js NPMs, undesirable dependencies can easily creep in. For example, imagine that somebody references a class or function in a place where it is not supposed to be used. This use creates a dependency that the developers of the class or function are not aware of. Any changes they make to their class or function could cause unexpected failures in another part of the system. After a short while, so many dependencies will have accumulated and the problem has worsened so much that the system can no longer be serviced or further developed.

Microservices, in contrast, communicate only via explicit interfaces, which are realized using mechanisms such as messages or REST. This makes the technical hurdles for the use of microservices higher, and thus unwanted dependencies are less likely to arise. In principle, it should be possible to achieve a high level of modularization in deployment monoliths. However, practical experience teaches us that the architecture of deployment monoliths deteriorates over time.

Easy Replaceability

Microservices can be replaced more easily than modules in a deployment monolith. Other components utilize a microservice via an explicit interface. If a new service offers the same interface, it can replace the existing microservice. The new microservice can use a different code base and even different technologies as long as it presents the same interface. This can often be impossible or difficult to achieve in legacy systems.

Small microservices further facilitate replacement. The need to replace code in the future is often neglected during the development of software systems. Who wants to consider how a newly built system can be replaced in the future? In addition, the easy replaceability of microservices reduces the costs of incorrect decisions. When the decision for a technology or approach is limited to a microservice, this microservice can be completely rewritten if the need arises.

Sustainable Development

Strong modularization and easy replaceability enable sustainable software development. Most of the time, working on a new project is straightforward, but over longer projects productivity decreases. One of the reasons is the erosion of architecture. Microservices counteract this erosion by enforcing strong modularization. Being bound to outdated technologies and the difficulties associated with the removal of old system modules constitute additional problems with deployment monoliths. Microservices, which are not linked to a specific technology, can be replaced one by one to overcome these problems.

Further Development of Legacy Applications

Starting with a microservices-based architecture is easy and provides immediate advantages when working with old systems: Instead of having to add to the old and hard to understand code base, the system can be enhanced with a microservice. The microservice can act on specific requests while leaving all others to the legacy system. It can also modify requests before they are processed by the legacy system. With this approach, it is not necessary to replace the legacy system completely. In addition, the microservice is not bound to the technology stack of the legacy system but can be developed using modern approaches.

Time-to-Market

Microservices enable shorter time-to-market. As mentioned previously, microservices can be brought into production on a one-by-one basis. If teams working on a large system are responsible for one or more microservices and if features require changes only to these microservices, each team can develop and bring features into production without time-consuming coordination with other teams. This enables many teams to work on numerous features in parallel and bring more features into production in less time than would have been possible with a deployment monolith. Microservices help with scaling agile processes to large teams by dividing the large team into small teams, each dealing with its own microservices.

Independent Scaling

Each microservice can be scaled independently of other services. This removes the need to scale the entire system when only a few pieces of functionality are used intensely. This will often be a significant simplification for the infrastructure and operations.

Free Choice of Technologies

When microservices are used in development, there are no restrictions with regards to the usage of technologies. This gives the ability to test a new technology within a single microservice without affecting other services. The risk associated with the introduction of new technologies and new versions of already used technologies is decreased, as these new technologies are introduced and tested in a confined environment keeping costs low. In addition, it is possible to use specific technologies for specific functions, for example a specific database. The risk is small, as the microservice can easily be replaced or removed if problems arise. The new technology is confined to one or a small number of microservices. This reduces the potential risk and enables independent technology decisions for different microservices. More importantly, it makes the decision to try out and evaluate new, highly innovative technologies easier. This increases the productivity of developers and prevents the technology platform from becoming outdated. In addition, the use of modern technologies will attract well-qualified developers.

Continuous Delivery

Microservices are advantageous for continuous delivery. They are small and can be deployed independently of each other. Realizing a continuous delivery pipeline is simple due to the size of a microservice. The deployment of a single microservice is associated with less risk than the deployment of a large monolith. It is also easier to ensure the safe deployment of a microservice, for instance by running different versions in parallel. For many microservice users, continuous delivery is the main reason for the introduction of microservices.

All these points are strong arguments for the introduction of microservices. Which of these reasons is the most important will depend on the context. Scaling agile processes and continuous delivery are often crucial from a business perspective. Chapter 4, “Reasons for Using Microservices,” describes the advantages of micro-services in detail and also deals with prioritization.

1.3 Challenges

However, there is no light without shadow. Chapter 5, “Challenges,” discusses the challenges posed by the introduction of microservices and how to deal with them. In short, the main challenges are the following:

Relationships are hidden—The architecture of the system consists of the relationships between the services. However, it is not evident which microservice calls which other microservice. This can make working on the architecture challenging.

Refactoring is difficult—The strong modularization leads to some disadvantages: refactoring, if it requires functionality to move between microservices, is difficult to perform. And, once introduced, it is hard to change the microservices-based modularization of a system. However, these problems can be reduced with smart approaches.

Domain architecture is important—The modularization into microservices for different domains is important, as it determines how teams are divided. Problems at this level also affect the organization. Only a solid domain architecture can ensure the independent development of microservices. As it is difficult to change the modularization once established, mistakes can be hard to correct later on.

Running microservices is complex—A system composed of microservices has many components that have to be deployed, controlled, and run. This increases the complexity of operations and the number of runtime infrastructures used by the system. Microservices require that operations are automated to make sure that operating the platform does not become laborious.

Distributed systems are complex—Developers face increased complexity: a microservice-based system is a distributed system. Calls between microservices can fail due to network problems. Calls via the network are slower and have a smaller bandwidth than calls within a process.

1.4 Conclusion

This chapter provided an overview of the concept of a microservice. It started with a definition of microservices. Then it answered the question “Why microservices?” Finally, the chapter ended with a discussion of the challenges associated with microservices.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset