Nowadays, trends show that market conditions are changing constantly and at a pace we have never seen before. New companies come into mature industries and completely disrupt them while existing companies that have been around for a long time are struggling to survive and to hold on to their market share.
Also, building highly available and resilient software has become an essential competency no matter what business you are in. Nowadays, all companies are becoming software companies. Let’s take for example companies in the retail industry. Before, most companies in this industry competed on who can make products available on the shelves with the lowest possible price. Now companies pursue more advanced and sophisticated techniques to lure customers. Nowadays, it’s all about predicting customers’ behaviors by deeply understanding customers’ sentiments, brand engagements and history of their searches and purchases. There is no doubt that companies who are harnessing these capabilities are more successful and profitable than those that do not.
To win in such market conditions, not only do companies have to have the capabilities to build these kind of solutions, but also they have to build them faster than their competitors. This is why many organizations are rethinking how they are architecting and building solutions so that they can better embrace changes in customers’ and market’s demands. Also, the rise of cloud computing has made organizations embrace design approaches that allow pieces of solutions to be scaled independently to optimize infrastructure resources consumption.
Software Architecture Evolution
Looking at how software designs have evolved over the years, initially applications were mainly monolithic applications targeting desktops. As internet became more prominent, a new style of applications emerged, namely Client-Server. In this type of architecture, we ran some code on desktops while another part of the application ran on a remote server somewhere. The server component tended to group both business logic as well as some kind of data persistence mechanism. As applications grew, there was a need to separate the business logic from the data persistence layer so a new style emerged namely 3-tier in which presentation layer, business logic and data persistence all lived on separate layers. The separation of layers have grown beyond the 3-layers giving birth to the concept of the n-tier architectures in which teams can create flexible and reusable components. The figure below shows a depiction of this type of architecture
Although the architecture above divides the solution into multiple layers, multiple flaws can be pointed out:
- The monolithic nature of the solution makes scaling the app not resource efficient
- Code base for the app tends to be large which makes it harder to change and maintain
- Collaborating on monolithic apps is challenging since multiple teams could be making changes to the code simultaneously which increases the likelihood of merge conflicts
- A fatal error in one of the components could bring the entire solution down
- Teams are bound to a specific technology stack for the entire solution
Because of the limitation mentioned above, a new design approach named Microservices has gained popularity in the last few years.
Microservices is an approach to application architecture in which an application is composed of small, independent and flexible components, each focusing on solving a single domain within the application. The figure below shows a depiction of such an approach
This approach solves a number of limitations imposed by monolithic applications. Some of the benefits you would get by adopting this approach include:
- Ability to deploy subset of the system. If a customer is not interested in one of the modules, they can choose not to deploy that module
- Ability to scale specific components of the system. If “Feature1” is experiencing an unexpected rise in traffic, that component could be scaled without the need to scale the other components which enhances efficiency of infrastructure use
- Improves fault isolation/resiliency: System can remain functional despite the failure of certain modules
- Easy to maintain: teams can work on system components independent of one another which enhances agility and accelerates value delivery
- Flexibility to use different technology stack for each component if desired
- Enhances the ability of developers to gain domain knowledge for a specific area
- Allows for container based deployment which optimizes components’ use of computing resources and streamlines deployment process
In my next post I will drill deeper into the last point which is a suitable deployment strategy for such an architecture. Stay tuned…