In recent years Microservices were all the rage and everyone wanted to build their application in a microservice style. But why? What are the actual goals of this architectural style? Let's have a look.
The goals of microservices span over many varied concepts. These benefits origin mainly from the concepts of distributed systems and SOA, are however pronounced by the tendency of microservices to take these approaches to their extremes.
Let's have a deeper look at the most commonly mentioned advantages of microservices:
Microservices provide an easier way to align the architecture of the system with the organization’s structure. Each application is responsible for a certain part of the given business domain and services correspond directly to the business capabilities of the company. Having separate applications and teams responsible for these applications, which map directly to departments of the organization, makes it easier to tailor these parts of the overall system to the needs of the specific department and its business cases and enables teams of technical and domain experts to collaborate efficiently
One of the key goals of microservices is to enable scaling in two different forms. The first form of scaling is of an organizational nature. By creating applications with a clear bounded context these applications are independently modifiable, deployable, and maintainable by a single team. This clear ownership reduces the friction and difficulties that occur when several teams with different goals are making concurrent modifications to a shared codebase. Therefore a larger number of teams is able to work on the same overall system in parallel
The second kind of scalability is the technical horizontal scalability of the application. It is common that certain parts of the system require more resources, or are under heavy or varying load. If for example, the part of the system that is responsible for sending out email notifications to users can not keep up with the number of messages to send, it is more efficient to spin up an additional instance of the specific service. The additional instance can then help with the processing of pending requests. In contrast in a monolithic system, the only possibility, in this case, would be to start an additional instance of the whole system which consumes a larger amount of resources, because it also needs to initialize the other capabilities of the overall system
The claim of improved resilience might sound counter-intuitive at first because distributed systems and therefore microservice systems typically increase the number of overall failures. There are however arguments that this actually increases the overall resilience of the system because it forces the architects to take failures into account early during the construction of the system. Having few and clear boundaries between the different parts of the overall system makes it possible to design sensible fallback mechanisms if an outage of certain non-critical applications occurs. This concept is known as the bulkhead pattern. For all applications, and for critical ones in particular, the possibility to provide redundancy in form of additional running instances, advanced monitoring, and automated scaling greatly reduce the risk of an overall system failure.
As previously explained large applications tend to result in a difficult and slow deployment process over time. This is especially a problem when a change to a certain part of the system needs to get deployed quickly. Fixing a critical bug in the UI of a monolithic system requires the whole application to be rebuilt and redeployed, even if the change is only in one line of a very specific part of the overall functionality. In contrast, when having multiple smaller applications, the problem can be fixed in the application responsible for the erroneous behavior, while all other systems are unaffected by recompilation and deployment
Technologies, tools, and approaches are constantly changing and evolving in the field of software development. It is possible that even if a problem is solved optimally by today’s standards, two or three years later the ecosystem around software construction has evolved in such a way that there is a superior approach to solving the same problem. In a monolithic system, however, it can be very hard to move from one technology or approach to another one, because the switch would require a vast amount of changes across the whole system. Small and independent microservices provide the possibility to be changed and sometimes even to be fully rewritten with little required effort.