Microservices today and tomorrow
Microservices is a popular development approach, which Netflix and Amazon have been successfully using for more than three years.
We noticed that the choice of microservices can sometimes be made unconsciously. In order not to follow trends blindly and choose the appropriate architecture for a particular product, we decided to cover the most frequently asked questions about microservices:
What are the advantages of microservices?
Which solutions are microservices best for?
What is microservice architecture?
The term "microservices" was introduced by Sam Newman in the book "Building Microservices": these are small, autonomous services that work together, focused on accomplishing only one thing at a time.
The idea itself of dividing the system into independent components isn’t new. The predecessor of the microservice architecture is service-oriented architecture (SOA), which also divides the business logic into components. In fact, microservice architecture is a particular case of SOA with a set of stricter rules.
The microservices have special features, which are also considered to be its advantages:
- Heterogeneity: the ability to build a system using various programming languages and technologies;
- Decentralized data management: each microservice contains its own data set, accessible to other microservices only through the appropriate interface;
- Infrastructure independence: each microservice is an independent unit, so you can make changes and deploy it independently;
- Scalability: to increase system performance, you need to expand only those services that need it.
Microservice vs Monolithic architecture
Microservices contrast with traditional monolithic architecture. Monolith means that the components of the product are interrelated and interdependent. If one ceases to work, all the others "fall off". At the moment there is a huge number of solutions and frameworks for the quick creation of a monolithic system.
The rapid development of IT-sphere imposes new requirements: the development of technologies, the changing needs of end-users - all this requires prompt reaction. If in 2005 it was normal to develop the product for several years, now the time dictates that the basic version should be released in a couple of months.
In such conditions, microservice architecture has more benefits than monolith:
- It is easier to change one of the micro services and immediately implement it, than to change the entire monolith and restart the entire infrastructure;
- New developers are more easily involved in the work - they do not need to study the entire system, you can only work on the part of the system you are responsible for;
- Microservices don’t depend on any platform, so it is easier to introduce new technologies in comparison with monolith.
Disadvantages of the approach
Though not everything is so perfect. Microservices impose limitations on product development and support:
- Complexity of initial development and creating infrastructure. Distributed systems are more difficult to develop, since it is necessary to provide for the independence of one microservice from a failure in another component;
- The development of distributed systems imposes additional costs on data exchange between microservices: it is necessary to choose the communication protocols between the components in order for the interaction to be as effective as possible;
- For a distributed system, it is difficult to maintain strict consistency: common parts of the system need to either be added to the shared library, but then if this library is changed, all dependent microservices need to be restarted or the common code stored in each of the microservices, but this code runs counter to the DRY principle (Do not repeat yourself), and it’s more difficult to maintain;
- Another structure of the development team. The team is divided into groups, each group fully develops only one microservice. Jeff Bezos, the head of Amazon, offers the optimal size of the team: that they can be fed with two pizzas, i.e. 7-9 people.
Release celebration in IT.place
It turns out that in the early stages of development, the results are faster if you use a monolithic structure. With the further development of such a system, its maintaining will become more difficult. Microservices require a lot of attention and skills from developers. You need to do a lot before the release of the first service: i.e, think through the infrastructure, understand the data transfer protocol, configure the deployment pipelines and change the way of thinking in software development. With the advent of the first ready-made service, the new functionality will appear faster than with a monolithic architecture.
Martin Fowler, one of the founders of the idea of microservices, proposed to combine both approaches into one - "Monolith First" (MonolithFirst). The main idea: "Do not start a new project with microservices, even with full confidence that the future application will be large enough to justify this approach." In a monolithic project it is easier to observe the connectivity of modules and add new features. Then the system is divided into several parts, and they are converted into separate microservices.
This is how you overcome the main disadvantage of creating a microservice architecture from scratch: there is no need to spend a lot of time on the initial division of the system into components and the organization of interaction between them. It is important to choose the right moment to start the separation into services: too early - and the microservices will not be filled with the necessary business logic, too late - the boundaries of the modules will be blurred, and it will be difficult to divide it into microservices. A sure sign that you need to start dividing is when the cost of the new functionality becomes higher than the its benefit. For example, if an application needed to connect to several payment systems, it is worth highlighting this logic in a separate service, rather than adapting the entire system for them.
The main disadvantage of this approach is described in the Don’t start with a monolith article: it is difficult to develop a monolithic structure, which can later be painlessly divided into components. With the transition to microservices, both the team and the development processes will be changed. For example, independent delivery of each service changes on the production server, versioning of components, fragmentation of the team into groups sufficient to service each service.
Solutions that require microservices
Pay attention to the project parameters: subject area, team qualification, release time, project load, number of external systems with which the application should communicate. If the project isn’t planned to have high loads and the constant addition of interaction with external services (payment systems, banks, external storages, etc.), it is better to choose a monolith. And vice versa: if the system should work under any loads and with a large number of services, the microservice architecture is mandatory.
At this very moment, we are developing a system for managing the network of pick-up points with the team. The customer orders a parcel in an online store and takes it at convenient time in one of the pick-up points with no queues at the post office and lost parcels. After analyzing the requirements, we chose microservice architecture, because one of the conditions for the existence of the system is its constant scaling: the system must interact with payment systems, banks, parcel aggregators, etc. And when we needed to integrate the system with another transportation company, we realized that we made the right architectural decision: each component is independent, that's why we developed a new microservice, regardless of the main part, without stopping the system.
The story about the experience of developing microservice architecture will be incomplete without mentioning the difficulties that inevitably have to be faced during development. A few months after the first release, we found performance subsidence in some parts of the system. This was due to the fact that several microservices took on too much business logic. Hence the main advice: always pay attention to how the application logic gets on with the components and be ready to "reshape" these components to achieve the best result. But even here we managed to fix the situation with minimal expenses: we divided some microservices into smaller ones, one of the components - proxy requests to the system - was simply remade from scratch by using faster technologies. And most importantly, we were able to parallelize all the work, and thanks to the independent delivery of changes, we were able to make the first optimization results absolutely transparent to users in just a few hours.
The consequences of these architectural solutions will be visible only after some time, because decisions at the beginning of the path are based on incomplete information. But if the microservice structure is chosen correctly, the benefits from its use will be greater than the shortcomings.