24
When it Pays to Choose Microservices
Hi everybody! My name is Victoria. Here at Typeable, I deal with the issues of application architecture, so I couldn't help asking the perennial question: To be or not to be? Specifically, is it worthwhile switching our solutions to microservices or not? To understand this, I've done small research of potential pros and cons. Here are my findings.
Microservices started gaining popularity in 2011-2014, smoothly replacing heavyweight SOA and monolithic solutions, where the architecture obstructed access to the rapidly growing market of cloud applications.
The approach itself evolved at the intersection of technologies out of the competitive need to bring the business to the next level instantaneously. Because of this, the solutions developed avalanche-like and quickly acquired add-ons, patterns, and CI/CD accessories. These reasons are still relevant for the business, and the interest in microservices has not declined over the last decade. At the same time, developing a microservice-based solution is a creative intellectual task for an IT team. It allows trying out state-of-the-art approaches and pinning down the conservatism dragons of previous solutions. That is, the challenge is quite noble.
However, the benefit of giving in to this magic is highly questionable.
Like any other fancy solution, microservices aren't always beneficial. Neither do they give a plaster for all sores.
Nevertheless, let's look into the matter.
The evolution of a typical IT solution can take the following path:
- An MVP startup is a solution mainly aimed to try the market and decide whether this concept works altogether. Complex technologies, advanced interfaces and high-load services are not needed here. Cost minimization and time to market are valued most of all at this stage. At times, MVP fails as early as at the stage of the focus group interview. Does it make sense to start building a microservice-based solution right away? My answer is no, don't give it a second thought. Time will be lost while you're thinking over the architecture and setting up the infrastructure. And this is the most valuable resource for a startup. Besides, it would be difficult to use the key profit factor of microservices – parallel development – with the startup team.
- Newborn monolithic solution. The application architecture is not fully verified, all internal and external services that will be used are not defined. The goals and objectives of end-users are not quite known. The data structure and functionality development strategy is not clear. Definitely, here it also doesn't make sense to start heading toward microservices, unless your team consists of profs for whom microservices are as easy as a pie.
- An old commercially available and stable monolithic solution with a thoroughly verified functionality; any arising issues are solved by skilful refactoring; the development is expected to be smooth, without any competition between functional blocks. Does it make sense to switch to microservices? Probably, this needs to be thought if the aim is to provide integration with external services, increase the load on the existing functional blocks, ensure their independent development and market launch or if you want to cut corners on the technology stack or improve the solution characteristics by reusing components. In this case, you should be ready to reinforce your team with necessary specialists and spend time to break the monolith down into independent or very loosely coupled functional blocks and then bring these blocks out from the monolith as separate services. This will definitely require additional resources, as well as time to train the team and search for suitable technologies.
- Multilevel monolith in DDD concept. The functionality is split into logically grouped isolated or loosely coupled blocks, which are still located within a monolithic structure; the logic is separated from the infrastructure. This is a good starting point for the migration to microservices.
- Distributed monolith. The development team has almost succeeded in breaking down the monolith, but something has obviously gone wrong. The services are too tightly connected to each other; explicit and implicit dependencies exist; the business is suffering because it sets forth requirements for one module, but it turns out that several modules need to be reworked; it's difficult to trace the effect of changes; testing and deployment require individual non-trivial approaches. Stop here and just think about it. Do you need microservices? Are there really any problems that cannot be solved by an initially monolithic solution? If you do need it, you should rebuild this pyramid but in the correct order.
- SOA solution. You shouldn't take microservices as the next step of the SOA evolution. It must be kept in mind that the main difference between the bus and the message exchange channel between services is that it is the bus that carries a significant portion of data conversion and orchestration logic. The message exchange channel between microservices, in its turn, must be fully reliable and straightforward. Its aim is to transmit a message. Implementing microservices in such solutions can be very costly because the supposedly "independent" modules can be closely coupled through the bus logic, and a simple replacement of this logic with aggregating patterns won't be sufficient. Moreover, the existing SOA solutions mostly use heterogeneous technologies and constructs which are difficult to adapt. Does it make sense to think about such migration at all? Usually, it doesn't. Most probably, the choice of SOA was driven by the complexity and diversity of the applications to be integrated into, the application scale, and the need to provide data consistency and the complex logic of data conversion. In this case, the choice is right. The microservices as an alternative should be considered only if the main part of the solution has become obsolete; when it's no more necessary to integrate with heavyweight application; if removing legacy code and migrating to simpler web solutions are on the agenda; if there is no need to maintain the high level of abstraction and data consistency but the speed of developing individual modules is still critical or it is necessary to enable independent work of separate teams.
- Monstrous monolith. The monolith full of legacy code and built on patches. The monolith developed so long ago that it's turned into a huge structure resistant to changes. The monolith consisting almost completely of spaghetti code. This is probably the only case when it makes sense to raze everything to the ground, sweep up the debris, and build a new solution on the ruins. Probably, based on microservices.
As a rule, the development team starts thinking about the microservices at the stage of startup or monstrous monolith. And maybe, this thought just jumps to the minds on the back of the microservice boom.
If:
- the aim is to develop a medium-sized non-trivial web application consisting of a set of loosely coupled or completely isolated modules;
- there are critical requirements for the application's resistance to loads and/or support of integration with external services (payment systems, banks, external storages etc.);
- the business requires significant acceleration of the development right now, plans to launch the changes on the market in all areas at once, and is not ready to wait for the sequential implementation of key changes in each area;
- it's necessary to use a heterogeneous technology stack (for the purposes of renovation, adaptation to market conditions, acceleration of internal processes, etc.);
- it's possible to distinguish the modules that allow reuse and support calls by various channels (authorization and authentication services, search engines, audit, etc.);
- the business sets forth requirements for the system blocks at different rates; the importance of the quick release of the individual block also varies;
- there's a commercial need to make frequent changes in an individual block in the future (to follow a trend or the marketing strategy);
- strategic business objectives require or will require a point-like scaling or different rates of changes in various points of the application;
- tactic business objectives require making multiple micro-changes in different modules of the system on the fly without disrupting the application as a whole (24/7 access and high probability of bugs due to the system complexity);
then you probably need to think about developing a solution using microservices.
Note that almost in every case it's not the development team who drives the decision-making but the business, and this is important. If microservices don't solve the business tasks, this is a waste of time and money. If the development team or the business itself has no idea of the current and strategic paradigm of the product, this is also a waste of time and money.
For example, interesting findings are provided in the research conducted by Camunda in 2018 among 354 companies in different countries and industries. Though the research revealed that 63% of enterprises support the adoption of microservices or are already adopting them, only 45% explicitly document the business processes. It creates a certain problem for evaluating the influence of microservice architecture on the implementation of these processes. At the same time, companies report that the top reasons for adopting a microservices architecture are: improved scalability of applications (64%), shortened development cycle (60%), support of digital transformation trends and integration with next-generation applications (54%), greater autonomy for development teams (54%); improved application resilience (50%).
However, based on the data provided by O'Reilly that ran a similar survey in 2020 among 1052 companies, 77% of respondents are using microservices and about one-third of respondents have been using them for the last three years. Of course, these two pieces of research cannot be compared, but the increasing popularity of microservices is obvious. Here similar issues were also found: incorrect decomposition and complexity of both the solution itself and the microservices management. Nevertheless, the surveys figuratively show that corporate culture takes the center stage. However, when it comes to the adoption of microservices, it's also an inhibitive factor.
Besides, there are some constraints you should take into account:
- You have a large team that has nothing to do :) It's a joke but it has a grain of truth. The minimum pool for one microservice is a team of six to nine persons, including developers, testers, and, advisably, an analyst. These people must not be occupied with anything else than their microservice or, as the last resort, two microservices. You can say, where there are two, there are three, and where there are three, there are four and so on. But this is a wrong path. Where there are two, there are no more than two. Period.
- Your DevOps architecture is configured to support independent development or you are ready to allocate resources and time for this. To start with, you do have DevOps. Make sure that you have.
- You are ready to organize test environments suitable for independent testing of microservices, as well as for testing of the microservices interaction, and you are ready to migrate from the concept of pure end-to-end testing to the structure consisting of modular, integration, component and end-to-end tests including placeholders development and contract publication.
- You are ready to spend time on failures or you've already fallen into all traps while developing your monolith and know exactly into which isolated services you can break it down without impairing the data quality, its processing speed and application reliability in general. At the very least, you clearly understand the data structure in each domain, know the business needs and can identify loosely coupled or completely independent domains. In no case should you link the microservice structure to the enterprise structure. Hierarchical schemes look pretty on paper, but in real life they often hide the pitfalls of poorly organized business processes.
- And, finally, make sure that the development doesn't involve legacy applications that must be integrated with, and that the data transactionality support is not critical in the domains you've identified (unless you know and are ready to use SAGA, the distributed transactions pattern).
Microservices are always associated with a degree of complexity, so if the business has no issues which could be resolved by microservices, don't add them, as the business will not appreciate this.
Alas, if the time to release hasn't been reduced, everything has gone wrong.
Most probably, you need to assess once again the potential sources of the problem:
- Too many microservices. Probably, it makes sense to replace the seven microservices overburdening five teams with only five? Or even two. In fact, the opinion that there must be many microservices is erroneous. In most cases, the company is neither Amazon nor Netflix.
- Poor analysis of business domains. There exist implicit dependencies, transactionality is required, there's no common solution for the architecture.
- Preliminary agreements on API development, testing, CI/CD cycle setup are missing/violated.
- The teams are either not autonomous or too autonomous, and the practice of experience exchange and retrospective is missing.
- The team's life activities are not managed and supported properly. There are conflicts over resources, there is no clear vision of the business purposes of both the application as a whole and individual services.
However, a situation may occur when it seems that something is going wrong but you're not quite sure of this.
To save you the trouble of reading another long text, I'm just placing a picture here with a number of examples.
Here let me finish my post and make brief conclusions on this subject:
- There's no use destroying what is working well just for the sake of fashion.
- If you've decided on destroying something, consult the property (business) owner first and explain all potential consequences. First of all, it's necessary to analyze whether this will produce a positive effect on the business processes and whether there are any needs that cannot be satisfied by an existing solution. Don't draw a nice model over the ruins. First of all, this will have negative consequences for the development teams.
- If the business approached you with this praiseworthy initiative, also explain the consequences. Business is business, they don't have to know about all pitfalls.
- Before you start, make sure that you have all resources and clearly understand the path.
- Don't miss the warning signs indicating that you've taken the wrong turn.
And finally. Most teams who have succeeded in using microservices had to rebuild their architecture on multiple occasions and followed the path of sequential monolith breakdown. So keep your head up.
As a final point, I would like to recommend several articles on this topic:
- Сhaos engineering make disciplined microservices by Shamik Mitra, Jun. 24, 21 · Microservices Zone
- When to use and not to use microservices by Hardik Shah, Dec. 24, 20 · Container Journal
- Microservices vs Nanoservices: Weighing Framework Options by Sudip Sengupta, Mar.10, 21 · BMC blogs
- Camunda Whitepaper Building Scalable Business Automation with Microservices by Sandy Kemsley, Dec. 2019 · Camunda
I found these materials interesting and worth noticing.
24