Monolithic Architecture
A monolithic architecture is the traditional unified model for the design of a software program.
Monolithic, in this context, means composed all in one piece. Monolithic software is designed to be self-contained; components of the program are interconnected and interdependent rather than loosely coupled as is the case with modular software programs. In a tightly-coupled architecture, each component and its associated components must be present in order for code to be executed or compiled.
Furthermore, if any program component must be updated, the whole application has to be rewritten
If you have a module monolith then all of the code for a system is in a single codebase that is compiled together and produces a single artifact. The code may still be well structured (classes and packages that are coherent and decoupled at a source level rather than a big-ball-of-mud) but it is not split into separate modules for compilation. Conversely a non-monolithic module design may have code split into multiple modules or libraries that can be compiled separately, stored in repositories and referenced when required. There are advantages and disadvantages to both but this tells you very little about how the code is used - it is primarily done for development management.
A non-monolithic allocation would involve deploying different versions to individual nodes at different times. This is again independent of the module structure as different versions of a module monolith could be deployed individually.
Whether the runtime is a monolith is independent of whether the system code is a module monolith or not. A runtime monolith often implies an allocation monolith if there is only one main node/component to be deployed (although this is not the case if a new version of software is rolled out across regions, with separate users, over a period of time).
The application is deployed as a single monolithic application. For example, a Java web application consists of a single WAR file that runs on a web container such as Tomcat. A Rails application consists of a single directory hierarchy deployed using either, for example, Phusion Passenger on Apache/Nginx or JRuby on Tomcat. You can run multiple instances of the application behind a load balancer in order to scale and improve availability.
Monolithic, in this context, means composed all in one piece. Monolithic software is designed to be self-contained; components of the program are interconnected and interdependent rather than loosely coupled as is the case with modular software programs. In a tightly-coupled architecture, each component and its associated components must be present in order for code to be executed or compiled.
Furthermore, if any program component must be updated, the whole application has to be rewritten
Module Monolith
If you have a module monolith then all of the code for a system is in a single codebase that is compiled together and produces a single artifact. The code may still be well structured (classes and packages that are coherent and decoupled at a source level rather than a big-ball-of-mud) but it is not split into separate modules for compilation. Conversely a non-monolithic module design may have code split into multiple modules or libraries that can be compiled separately, stored in repositories and referenced when required. There are advantages and disadvantages to both but this tells you very little about how the code is used - it is primarily done for development management.Allocation Monolith
For an allocation monolith, all of the code is shipped/deployed at the same time. In other words once the compiled code is 'ready for release' then a single version is shipped to all nodes. All running components have the same version of the software running at any point in time. This is independent of whether the module structure is a monolith. You may have compiled the entire codebase at once before deployment OR you may have created a set of deployment artifacts from multiple sources and versions. Either way this version for the system is deployed everywhere at once (often by stopping the entire system, rolling out the software and then restarting).A non-monolithic allocation would involve deploying different versions to individual nodes at different times. This is again independent of the module structure as different versions of a module monolith could be deployed individually.
Runtime Monolith
A runtime monolith will have a single application or process performing the work for the system (although the system may have multiple, external dependencies). Many systems have traditionally been written like this (especially line-of-business systems such as Payroll, Accounts Payable, CMS etc).Whether the runtime is a monolith is independent of whether the system code is a module monolith or not. A runtime monolith often implies an allocation monolith if there is only one main node/component to be deployed (although this is not the case if a new version of software is rolled out across regions, with separate users, over a period of time).
Example
Let’s imagine that you are building an e-commerce application that takes orders from customers, verifies inventory and available credit, and ships them. The application consists of several components including the StoreFrontUI, which implements the user interface, along with some backend services for checking credit, maintaining inventory and shipping orders.The application is deployed as a single monolithic application. For example, a Java web application consists of a single WAR file that runs on a web container such as Tomcat. A Rails application consists of a single directory hierarchy deployed using either, for example, Phusion Passenger on Apache/Nginx or JRuby on Tomcat. You can run multiple instances of the application behind a load balancer in order to scale and improve availability.
Resulting context
This solution has a number of benefits:
- Simple to develop - the goal of current development tools and IDEs is to support the development of monolithic applications
- Simple to deploy - you simply need to deploy the WAR file (or directory hierarchy) on the appropriate runtime
- Simple to scale - you can scale the application by running multiple copies of the application behind a load balancer
However, once the application becomes large and the team grows in size, this approach has a number of drawbacks that become increasingly significant:
- The large monolithic code base intimidates developers, especially ones who are new to the team. The application can be difficult to understand and modify. As a result, development typically slows down. Also, because there are not hard module boundaries, modularity breaks down over time. Moreover, because it can be difficult to understand how to correctly implement a change the quality of the code declines over time. It’s a downwards spiral.
- Overloaded IDE - the larger the code base the slower the IDE and the less productive developers are.
- Overloaded web container - the larger the application the longer it takes to start up. This had have a huge impact on developer productivity because of time wasted waiting for the container to start. It also impacts deployment too.
- Continuous deployment is difficult - a large monolithic application is also an obstacle to frequent deployments. In order to update one component you have to redeploy the entire application. This will interrupt background tasks (e.g. Quartz jobs in a Java application), regardless of whether they are impacted by the change, and possibly cause problems. There is also the chance that components that haven’t been updated will fail to start correctly. As a result, the risk associated with redeployment increases, which discourages frequent updates. This is especially a problem for user interface developers, since they usually need to iterative rapidly and redeploy frequently.
- Scaling the application can be difficult - a monolithic architecture is that it can only scale in one dimension. On the one hand, it can scale with an increasing transaction volume by running more copies of the application. Some clouds can even adjust the number of instances dynamically based on load. But on the other hand, this architecture can’t scale with an increasing data volume. Each copy of application instance will access all of the data, which makes caching less effective and increases memory consumption and I/O traffic. Also, different application components have different resource requirements - one might be CPU intensive while another might memory intensive. With a monolithic architecture we cannot scale each component independently
- Obstacle to scaling development - A monolithic application is also an obstacle to scaling development. Once the application gets to a certain size its useful to divide up the engineering organization into teams that focus on specific functional areas. For example, we might want to have the UI team, accounting team, inventory team, etc. The trouble with a monolithic application is that it prevents the teams from working independently. The teams must coordinate their development efforts and redeployments. It is much more difficult for a team to make a change and update production.
- Requires a long-term commitment to a technology stack - a monolithic architecture forces you to be married to the technology stack (and in some cases, to a particular version of that technology) you chose at the start of development . With a monolithic application, can be difficult to incrementally adopt a newer technology. For example, let’s imagine that you chose the JVM. You have some language choices since as well as Java you can use other JVM languages that inter-operate nicely with Java such as Groovy and Scala. But components written in non-JVM languages do not have a place within your monolithic architecture. Also, if your application uses a platform framework that subsequently becomes obsolete then it can be challenging to incrementally migrate the application to a newer and better framework. It’s possible that in order to adopt a newer platform framework you have to rewrite the entire application, which is a risky undertaking.
Known uses
Well known internet services such as Netflix, Amazon.com and eBay initially had a monolithic architecture. Most web applications developed by the author had a monolithic architecture.Reference
Articles:As these articles are really long to read, I will recommend adding this extension to Chrome. Read Aloud: A Text to Speech Voice Reader
Videos:- Introduction to Monolithic Architecture and MicroServices Architecture (MUST READ)
- Microservices vs Monolithic Architecture
- Pattern: Monolithic Architecture
- Should you always start with a monolith? (MUST READ)
- Monolithic vs. Microservices Architecture (MUST READ)
- How can StackOverflow handle so much load while they're a monolithic application?
- What are microservices really all about? - Microservices Basics Tutorial (MUST SEE)
- What are Microservices and how are they different from Monoliths? (MUST SEE)
- What is a Monolithic Architecture? Do you need one?
- Monolithic
READ THE COMMENTS TOO....
Regarding micro-services, I would like to add a few pointers.
ReplyDelete1. Even with Larger Systems, sometimes micro-services may not be always a good fit. For example, in stream processing systems where processing is centered around per record based processing and micro service calls would worsen the performance.
2. Deployment of micro-services is far more complicated than monoliths. Because usually with Monoliths, it's a single unit of deployment(Eg: war file if WebApps) but with microservices depending on the scale and grain of the micro-services, there will be N number of deployments needed. It becomes difficult to keep track of the status of each service and in turn, knowing the readiness of the overall system will be a challenge.
3. Microservices are a great fit for mobile and web applications but when it comes to Big-Data world, it would complicate the overall process. For example, In the Web applications, we mostly deal with Web Server, Database and its easier to containerize them but when it comes to distributed systems containerizing them will be a challenge.
Load balancing is very difficult in Monolith. Example, take Flight reservation system application as example. Every body uses search page to search flights. But only few goes to the booking of a searched flight. So search operation is taking too much load on that. So In Micro services, We can create as many instances as we can of Search micro service alone. I agree deployment and monitoring is very difficult in Micro services , but using Eureka or Spring admin console, we can have all the instances and monitor them easily.
ReplyDeleteFor small scale application development which scaling is not required, then Monolith is best.
Speaking of microservices, there are actually lots of advantages of this approach. For example, since microservices architecture is based on small components, it’s easier for them to scale up and down following all the requirements for one certain component. Take a look at this guide to learn more about advantages of microservices architecture.
ReplyDelete