Microservices architecture is a pattern for organizing computer systems into services that can scale with demand. Back in the 1990s, traditionally an internet company was supposed to run a big monolithic program on a server which is maintained due to the promise to facilitate end customers. To serve an increase in traffic a popular company would simply add more instances of the monolith.
Monolithic architecture does not possess many positive features rather it becomes challenging. A monolith centralizes the codebase so the engineers can step through any part of the code when they are debugging the application. Also, user requests are completely served by a monolith as it does not require many calls across a network which reduces the chances of network failures. Most software companies have their code in a monolith pattern. When these monoliths have problems, fixing them in a centralized location leads to tight couplings that are difficult to break, which can cause a variety of problems for teams working in the same environment [22]. If the program is too big it will be impossible to run it on a typical traditional machine.
3.1. Architecture Comparison between Monolithic and Microservices
Monolithic architecture is the usual place to start when developing an application. When creating and deploying a monolithic application, every component is included in a single unit. Figure 1 shows the components of a typical monolithic application, which includes a user interface (UI) layer, business logic layer, and data access layer that interacts with the database [17]. Development may begin more quickly with monolithic design than with microservices, hence this approach was dominant. The major issue with monolithic applications is that it gets worse in complexity when the application structure gets bigger. It becomes more difficult to integrate existing components or add new features and time complexity increases with adjustments to existing ones [5, 21]. The large enterprise application requires a lot of time to become comfortable with its code and architecture.
As a result, new developers become more confused and the possibility of bugs and errors also increases due to uncertain situations where to perform modifications. Refactoring modifications may be seen in many areas of a large monolithic application. Due to the multiple places where their changes have an impact and the difficulty of proving that everything is still functional, developers become reluctant to undertake significant refactoring efforts. This may even lead to circumstances where refactoring is disregarded because it is too dangerous which could result in a form of unclean code. Developers may duplicate more code since it is nearly impossible to identify existing code that accomplishes the same task when they are unfamiliar with the source. Furthermore, because there are no clear borders between modules [5], it is possible that the modularity of the software decreases as it grows.
Beyond the size of the enterprise applications, there are other factors to consider when breaking up a monolith application. In microservice architecture, it is more sensible for the software development teams to take ownership of various components of the code if they are located in different areas and their communication is insufficient [11]. This facilitates the development process because teams in various geographic locations are no longer at the chance of changing typical software components. If a team is responsible for a service, it is more likely that the code will remain clean and those technical problems will be resolved more quickly because no one else will be held accountable for the code's quality. This split also makes it much quicker and simpler for the team to publish a new version of the service to production because it decreases the need for comprehensive coordination and communication with other teams.
A monolithic approach might be the best option for small software applications where there is no need for many software development teams [3]. If the application is small and will likely stay where the future is predictable, expert teams are geographically close to one another, and communication between them is simple then a monolithic application may be a better choice [3]. In addition, the domain's complexity is well understood among teams, and there is difficulty to determine whether to utilize a monolithic architecture rather than microservices [17]. It is possible to have a monolithic with strong modularity and clean code, but maintaining that modularity requires more effort when compared with microservices application. Microservices naturally give modularity and make enterprise application modularity code more efficient.
In Fig. 1; there are three-layer layers that are quite popular, particularly in enterprise software applications. As we can see, there is generally only one database, therefore if part of the data needed to be normalized and scaled into different databases, this type of architecture would not be able to accommodate it. This bounds the conclusions that the teams cannot fulfill demands to meet the growth and firm requirements. The plurality of the data, for instance, would work just fine in a relational database management system, but some of the application data need more scalability and performance, which is what MongoDB, for instance, would offer. Usually there is only one database where several teams must correspond to database schema changes, which slows down software development [5].
It is possible to choose the relational database (SQL) or non-relational database (NoSQL) for each service when using microservices, as demonstrated in Fig. 2. Now software development teams have more possibilities in terms of desiring their implements [17, 22]. When the database contains fewer tables and the microservice has entire control over the data and database schema, designing and scaling the database becomes relatively straightforward. Some services operate without a database. Figure 2 also demonstrates that microservices frequently interact with one another.
These two architectural types are contrasted in Table 1. As we can notice, both architectures have their own advantages and disadvantages. We can conclude from the table that dealing with large enterprise applications makes the microservice architecture style more appealing. The technological difficulties that microservices present might not have enough time to spend off with smaller projects.
Table 1
Comparing Monolithic vs Microservices Architecture.
Description | Monolithic | Microservices |
Scalability | Difficult to upgrade | Easy to scale per service |
Architecture | Single build of a unified code | Collection of small services |
Programing language | Hard to change, take a lot of time to rewrite code | Language can be selected per service |
Time to market | Complicated and time-consuming deployments | Easy to build and deploy |
Development | Depend on the team to perform the parallel operation in same application code | Team don’t have to work parallel because each service can be delivered independently |
Reliability | If service fails, the entire application goes down | Very reliable. If service fails, the application will not go down as a whole |
Maintainability | Large code base intimidating to new developers | Small code base easier to manage |
Agility | Not flexible and impossible to adopt new tech, language or frameworks | Integrate with new technologies to solve business purposes |
Testing | End-to-end testing | Independent components need to be tested individually |
Resiliency | One bug or issue can affect the whole system | A failure in one microservice does not affect other services |
Security | Communication within a single unit makes data processing secure | Interprocess communication requires API gateway raising security issues |
Price | Higher once the project scales | Higher at the first development stages |