Design of Modern Distributed Systems based on Microservices Architecture

Distributed systems are very commonplace nowadays. They have seen an enormous growth in use during the past few years. The idea to design systems that are robust, scalable, reliable, secure and fault tolerance are some of the many reasons of this development and growth. Distributed systems provide a shift from traditional ways of building systems where the whole system is concentrated in a single and indivisible unit. The latest architectural changes are progressing toward what is known as microservices. The monolithic systems, which can be considered as ancestors of microservices, cannot fulfill the requirements of today’s big and complex applications. In this paper we decompose a monolithic application into microservices using three different architectural patterns and draw comparisons between the two architectural styles using detailed metrics that are generated from the Apache JMeter tool. The application is created via .NET framework, uses the MVC pattern and is fictive. The two comparable apps before testing with Apache JMeter, will be deployed in almost identical hosting environment in order to gain results that are valuable. Using the generated data, we deduce the advantages and disadvantages of the two architectural styles. Keywords—Distributed systems; microservice; monolithic; web services; JMeter


I. INTRODUCTION
Microservices are a new development, coming into light just a few years ago. They offer many advantages compared to the old monolithic architectures. That is why many of the big tech companies have successfully made the switch to microservices. Currently, the monolithic architecture is the default model for creating a software application. Its trend is decreasing as it cannot keep up with the demands and the challenges of the new applications that are now quite big and complex.
In the monolithic architecture, application is built as a single indivisible unit. This usually means that the application has three core components that interchange information with each other: a user interface, a server-side and a database [1]. This architecture is characterized by a huge code base and has almost no modularity. Because they have a single code base, they can become so large and hence difficult to maintain. The whole application will need to be redeployed from a single small change in the code. More crucial is the fact that it is not very reliable since a bug in any part of the code can bring down the whole application [1].
Monolithic architecture, however, has some subtle advantages and with some tweaks it can still be useful to many modern applications. These include: the easiness of deployment (since only one file needs to be deployed), the easiness of development (compared to the microservices) and the network latency and security which are more noticeable in the microservices architecture. Monolithic architecture is also very easy to test. We can do so by simply launching the app and testing the UI with Selenium. However, some of the drawbacks of this architecture have made the switch to microservices a necessity [2].
Because today's apps are big and complex, in order to be useful, they need to be robust and reliable. The resources must be utilized efficiently so the users can get a seamless experience while surfing the app. Many components of the app might have different resource requirements. Some might need more CPU cycles, some others more memory etc. This imposes the need to scale the different components, independently. Scaling in the monolithic architecture is done by creating copies of the app. This means that all of these copies will access all of the data which in turn makes caching less effective and increases memory consumption and I/O traffic [2].
As authors in [3] put it, one of the problems that can arise from the monolithic applications is the evolvement into a "big ball of mud" state, which is a situation in which none of the developers understand the entire application. To overcome the obstacles, microservices provide a very reasonable and effective architectural style, which as mentioned, are increasingly being used and deployed in many modern applications. In fact, microservices are considered as the future of distributed systems.
On the other hand, despite its name, microservices are by no means, small. In this architectural style, the application is made up of a suite of small devices, all of which have their own unique codebases.
Microservices use lightweight mechanisms, somewhat like an API, to communicate between different services. Contrary to monolithic architecture, these services can be deployed together or separately. These services are loosely coupled (or headless) making this architectural style mostly decentralized [3]. www.ijacsa.thesai.org It must be understood that a microservice is not a layer within a monolithic application. It has its self-contained functionalities with clear interfaces, and through its own internal components, must implement a layered architecture. According to the author in [4] this architecture follows the Unix philosophy of "do one thing and do it well". In the following sections we will explore some of the main advantages of microservices and whether it is a good idea to fully deploy an application into microservices.
The research questions we will try to answer from our experiment and analysis of literature, are  Does decomposing into microservices impact the system's average response time?
 Is it always adequate to develop an app using the microservices logic?
 To what extent should the monolithic application be decomposed into a microservice?

A. Design and Structure of Monolithic Applications
A monolithic application describes a single-tiered software application in which the user interface and data access code are combined into a single program from a single platform. Schematically, this can be seen Fig. 1.
It is self-contained, and independent from other computing applications.
The design philosophy is that the application is responsible not just for a task but can perform every step needed to complete a particular function. Layered architecture is a common pattern seen in monolithic applications. This architecture allows for the technical capability to be changed fairly easily, especially if they are isolated to a particular layer [5].
The main idea behind this architecture is the separation of concerns, the main monolithic application components which include authorization, presentation, business logic and database are organized into four main categories or layers:  The presentation layer contains all of the classes responsible for presenting the UI to the end-user or sending the response back to the client.
 The application layer contains all the logic that is required by the application to meet its functional requirements.
 The domain layer represents the underlying domain, mostly consisting of domain entities and, in some cases, services.
 The infrastructure layer (also known as the persistence layer) contains all the classes responsible for doing the technical stuff, like persisting the data in the database including DAOs or repositories.
An example of monolithic system architecture of realworld application is shown on Fig. 2. The diagram shows main components needed to build an Ecommerce application which authorizes costumer, takes an order, checks products inventory, authorizes payment and ships ordered products [6].  Despite having many components which are independent from each other the system as shown in Fig. 2 is build and deployed as one application. With issues regarding maintenance, response time and scaling, monolithic architecture should be avoided when designing large and complex applications which may be used in different environments with different configurations or in applications which may change and need to be frequently updated. This paper is structured as follows: Section II presents the state of the art, Section III methodology and results, Section IV case study and Section V conclusions.

II. STATE-OF-THE-ART
As mentioned previously, over the last decades, industry demands have pushed software design and architectures in various directions. The ever-growing complexity of enterprise applications, along with change and evolution management ushered in the rise of different architectures with an aim to replace or improve the traditional unified software designing model known as monolithic architecture.
Various architectures (besides the eminent ones) have been designed, researched, and used in industry, in recent years there has been a lot of hype regarding the new architectural model called microservice architecture. Considered new, microservice architecture has found itself being researched and compared a lot with existing architectures including SAO, serverless and monolithic architectures. Most of research www.ijacsa.thesai.org studies were oriented on performance analysis, cost, and resource usage.
In a research that was done by Singh and Peddoju, the performance of a monolithic application is compared to a microservices application, the applications that were built were tested for their response time and throughput. Obtained results made it clear that microservices architecture has a better performance especially when it is used for a large number of requests [7]. Similar approach was used by the IBM research team in Tokyo, they compared the performance of the monolithic and microservices applications in different environments and configurations. The results were compared for throughput, scalability, number of CPU instructions for request and number of clock cycles to complete one instruction. The results showed a significant performance boost in monolithic architecture applications in many configurations and environments, which in a way contradicts the results shown by Singh and Peddoju [8].
Microservices are often compared to Service Oriented Architecture. The research paper done by Cerny, Donahoo and Pechanec compares and analyses microservices, serviceoriented architecture and self-contained systems in terms of service and architecture, characteristics, integrations, capabilities, and flexibility. The drawn conclusion presented at the end of the paper favorizes SOA for large systems with many shared components and suggests using microservices for medium distributed systems which may need to scale in the future [9].
A different approach was used on research paper done by Chen, Li and Zheng from Nanjing University. This paper discusses ways to decompose a monolithic application to microservice architecture. Throughout the paper the researchers used a top-down analysis approach and developed a dataflow-driven decomposition algorithm. They defined a three-step procedure for process decomposition involving business requirement analysis, usage of dataflow-driven algorithm and individual modules extraction [10].
According to the fourth annual Developer Ecosystem Survey conducted by JetBrains, about 85% of 19,696 developers who were surveyed in the beginning of 2020, use the microservices-based system design [11]. The programming languages of choice for building microservices are JavaScript and TypeScript; REST APIs are used for communication between microservices the most, whereas the favorite cloud provider for microservices is Amazon Web Services, as shown in [12].
Improving scalability and improving performance are two of the most important topics when it comes to microservices. In the State of Microservices 2020 research project [12], over 650 developers (CTOs, Lead Developers, and Senior Developers) were asked to rate in scale 1-5 how they enjoy working with microservices when it comes to different aspects.
As shown in [2] Table I, most experts are happy with microservices for solving scalability issues, whereas maintenance and debugging seem to be a challenge for them. Regarding security, there are still many challenges due to the complexity of the developments, the hardness of monitoring, and debugging and auditing of the full application in foreign environments [13].
Before moving to microservices, we should be aware of the architectural challenges. Some of the main architectural challenges, as presented in [14], are: 1) Dispersed business logicmicroservices approach distributes the operating logic and execution flow of complex features among many applications.
2) Lack of distributed transactionsattempting to maintain consistency among many microservices involved in business transaction is extremely complicated.
3) Inconsistent dynamic overall stateit is related to lack of distributed transactions. Overall consistency gets more complicated with data that is geographically distributed data within the same domain because of sharding and data replication.
4) Difficulty in gathering composite datajoining data for analytics of the overall system in a microservices architecture is not straightforward. 5) Difficulty in debugging failures and faultsattempting to pinpoint the source of an error might require debugging multiple applications. Identification of the root cause of the problem is difficult primarily because of deep hierarchies of microservices (AC1) and the inability to determine the exact state of the system (AC3).
6) Difficulty in evolvingsoftware evolution is a hard concept in an environment different where parts of the system evolve continuously, in parallel.

III. METHODOLOGY AND RESULTS
This section gives an overview on which methods and tools were used.
The goal of this section is to offer a way of passing between monolithic architecture to microservices approach and comparing them. So, we are going to demonstrate how to identify key design issues of monolithic applications and how they should be reflected in microservices approach. For that purpose, we will use a monolithic application that is developed in Model-View-Controller approach, which is based on monolithic architecture, and we will try to offer a way of decomposing it in microservices approach.
We are aware that there are a lot of design patterns that exists for developing web applications. But based on usage we www.ijacsa.thesai.org have decided to use MVC as one of most used architectural patterns for developing web applications that are based on monolithic architecture and not only.

A. E-Shop Monolithic Application
As we said earlier, we will use an application that uses MVC approach, which is developed in Asp.NET Core with MVC approach. Before analyzing this application, we want to make purely understood that the term "monolithic", in this context refers to the fact that these applications are deployed as a single unit, not as a collection of interacting services and applications [15].
Application that we have developed for this paper is based on application of Microsoft [16], for e-shop. The main reason why we have chosen to develop an e-shop application is to demonstrate how to pass between monolithic to microservices is because there is an almost perfect example that microservices should be used there.
In Fig. 3, we have presented schematically controllers of the application that are developed.
As is can be seen there are four controllers that monolithic application currently has. First controller, Order, is for handling requests that are for ordering items on application. Second controller, Product, it is used for managing products. The third controller, Home, is for main and privacy terms. The last controller which is default controller for authentication and authorization is Identity, it used to manage accounts and roles. In Fig. 3 we have presented Identity as a Controller, but in latest version of Identity Microsoft uses Razor pages for this module, but we will abstract this, and we will consider as a controller.
In Fig. 4 we have presented schematically structure of application that is developed as a monolithic application in Visual studio.
As it can be seen from Fig. 4, all application logic, including presentation, business and data access logic is in one place.
In the next section we will offer a way of passing microservices approach and how we should identify parts of application that should be microservice itself.

B. Decomposing to Microservices
In this section we will try to offer a way of how to decompose E-shop application to microservices approach.
Before starting to identify microservices we want to make purely understood that there is no general method that can be applied to every monolithic application. This means that we need to study very deeply application before architecting to microservices.
For E-Shop application, the first thing that must be transformed to microservice is Identity service, which is used for authentication and authorization purpose. One the most important services in E-Shop application, and in most applications, is security. Identity service is an IdentityServer4 [17], which is a typically used for managing authentication and authorization in microservices environment. Typically, IdentityServer4 acts as a middleware [18] that adds the spec compliant OpenID Connect and OAuth 2.0. With IdentityServer4 all access to microservices can be managed and this service is responsible for generating access token for clients.
Other important microservice for E-Shop application is product microservice, which is responsible for managing products for this application. So, this microservice can register new products, edit them, or see details about products. So, this microservice does only one thing but it does in a perfect way.
Last microservice is responsible for handling orders of customers. So, this microservice is focused only on processing orders, and offers a payment for orders.
For testing purpose is developed a client which will use microservices over RESTful API [19]. A schematic presentation of E-Shop application decomposed to microservices is displayed in Fig. 5. As it can be seen from Fig. 5, in this case we have 3 microservices, which we have described before. This decomposition offers a very good way to deal with scenarios where ordering a product is not possible, still application can offer service by listing all product that are there. So, with this decomposition we have archived a good way to handle problems with no function of order product, but order product currently contains functionality for checkout and payment. As part of comparison is this model of decomposition with E-Shop monolithic system, and other types of microservices architecture that will be presented.

Controllers
As it can be seen from Fig. 5, the main problem with decomposition of E-Shop application in microservices architecture that is offered, is Order microservice, which needs to be decomposed to three microservices. These 3 microservices that will be derived from Order microservice are:  Order microservice.
 Checkout microservice and.
Schematically this decomposition is presented in Fig. 6.
With decomposition of Order microservice, are archived many things.
The last feature that will be applied when decomposing to microservices, in Fig. 6, is adding an API Gateway. Schematically this is presented in Fig. 7.
Decomposition that has been displayed in Fig. 7, contains an API Gateway, which acts as reverse proxy, hides functionality of microservices that are currently implemented in E-Shop application. This is a very good place to implement security for microservices.

C. Load test Comparison
In this section we will compare monolithic application with microservices for our fictive application. Comparison is made by using Apache JMeter [20] with different parameters.
To have results that are comparable with each other we have hosted to Docker, with Linux container, all microservices, monolithic application and Client which consumes microservices is hosted in Internet Information services for Windows. For this purpose, we have deployed to test environment which is identic for microservices and monolithic application. Database is in Microsoft SQL server and contains same tables for both applications. Architecture of infrastructure for monolithic and microservices is presented in Fig. 8. The first scenario will perform Get request to home page, then to list of products and finally to edit product page. All three requests are Get requests. Parameters of testing are set same for all applications. Parameters in Apache JMeter are: After creating test plan in Apache JMeter, we have gained results as can be seen in Table II.
In second comparison, as additional will be added post request which is responsible for adding new products to database. Parameters for Apache JMeter are same as above. After creating test plan in Apache JMeter, we have gained result as can be seen in Table III. The final comparison will be made to order part. There will be added get request for checkout, order detail for specific product, update to database number of orders and finish payment.
After creating test plan in Apache JMeter, we have gained result as displayed in Table IV.  Very important statistic that can be derived from Table IV, is average response time that is from First and Second microservice. Decomposing to Microservices of course that has many benefits, but sometimes benefits that can be archived from decomposing might hurt performance of the system. This is proved by results displayed in Table IV.

IV. CASE STUDY
In case study will be discussed for complex system, which is implemented in Kosovo, which is Health Insurance Fund Information System of Kosovo. Because of data sensitivity we have decided to not use this system to decompose to microservices approach, so we have used a fictive application.
Results that are archived by using fictive application are very important and there can be draw parallel with Health Insurance Fund Information System and other systems.
Based on results that are archived there should be made a tradeoff between current architecture that has this system, which is monolithic application and is developed in Asp.Net, to decompose to Microservices approach. Again, based on results from Results for First Test Table II, Table III and Table  IV, is evident that decomposing to microservices would decrease average response time, but benefits that could be archived from microservices, especially for this system, are bigger than the average response time. Benefits that will be archived are same as mentioned in Section C of III.

V. CONCLUSIONS
It is obvious that microservices offer a lot of advantages compared to the traditional monolithic architecture. Many of the core functionalities of microservices were described throughout the paper. Our approach in this paper, was to analyze and then compare the same application but developed with the two architectural styles. From the results obtained we saw that microservices can increase the system's average response time since there are different services that need to communicate and exchange information with one another. Testing for different parameters with Apache JMeter we saw the differences in response times between them. Results from Apache JMeter, for three cases, also told that not only response time, but also error rate is better than architecture based on microservices. On the other hand, architecture based www.ijacsa.thesai.org on microservices performs better in number of Kilo Bytes send and received per second, in case when test scenario contains post method as can be seen from Table IV. One big advantage of microservices, is that they are not tied to a programming language. They also overcome the cumbersomeness of dealing with databases as we saw while developing our fictive application. To conclude, choosing whether to use the monolithic or the microservices architecture is not always clear cut. It all boils down to the type of application and what the developer wants to achieve. Big applications will benefit from the robustness, efficiency, and the well-organized code that the microservices make possible.