Not so long ago… if a web page was slow, you would blame the device performance, or the Internet connection speed. You would get yourself a tea or a cup of coffee before sitting down for an online banking session so it would not feel like waiting.
Anyone facing a similar experience today would immediately switch to another website or a bank with better online services. This helps us realize that the way we should design and write software today is much more different and challenging that it used to be just a few years ago. It is no longer enough to have a consistent, valuable and user centric business logic. Powerful user hardware, security threats, high Internet bandwidth, increasing number of online users and many more other factors are pushing the limits of how software gets built.
Gaming, e-commerce, telecom, banking, electronic payments, media providers, online betting, most business domains today cannot survive without having its software scalable, fault tolerant, responding in a timely manner, adaptive to variable workload, and I am sure that you can add a few more to this list. Forced to re-think technologies and best practices, people sharing the same impediments teamed up and identified patterns that led to better solutions. This process lasted over a decade for certain business domains like telecom. During this time, the emerging principles were successfully applied without being properly formalized.
In 2013, Jonas Bonér, Dave Farley, Roland Kuhn, and Martin Thompson made public a set of core principles that help build software that can withstand the needs of businesses like LinkedIn, Walmart, PayPal, Netflix and may other major worldwide companies. The Reactive Manifesto provides the definition for Reactive Systems and the strategic advantages that they bring to the table. This approach had a huge success and many software solution providers, middleware vendors and Fortune 2000 companies have embraced these concepts.
Reactive System Architecture in a nutshell
Reactive System Architecture is a set of practices and design principles meant to make the system responsive, resilient, elastic and message driven. This allows multiple individual applications to perform as a single unit, reacting to its surroundings while remaining aware of each other.
A Reactive System will always:
- Provide rapid and consistent response times.
- Be resilient to failure such that parts of the system can fail and recover without compromising the system as a whole. After a failure, the system must remain responsive. This is achieved through the combined use of replication, isolation, and delegation. This is also known as high-availability.
- Scale up and down depending on varying load conditions. Elasticity is the system’s ability to shard or replicate components and distribute inputs among them.
- Have its components loosely coupled and isolated, communicating between each other via asynchronous message passing.
What’s in it?
The Reactive Manifesto it is not a “definition of done”, but more a starting point for building Reactive Systems. Improving each nonfunctional criteria of your system becomes a craft. For example, instead of a system being simply elastic, it can be designed to have predictive scaling. Or, instead of failing under massive load, a component can be enhanced to provide backpressure. One way to achieve consistency is to separate commands from queries. This means separating the data models for updates and reads which results into an approach that tracks each individual data change rather than the last state of the entire data model. This is also known as CQRS.
Building reactive systems requires a reactive mindset. As a developer the key is to embrace the fact that you no longer invoke your components and tell them what to do, you just let them do their job whenever they receive an event. Reactive Programming is all about decomposing the problem into steps and making them execute in an asynchronous and non-blocking fashion. This simplifies isolating and encapsulating internal business logic and managing the information flow. It also makes things easier to test. Either you use an object-oriented programming language or a functional one, the mindset remains the same, only the tools and libraries differ.
Hardware is no longer an issue. Servers with 64 vCPU and 128 GB of memory are now one click away. One of the challenges that we are currently facing is figuring out how to build our microservices in such a way that we turn processing power into responsiveness, while ensuring that we make the best of tomorrow’s hardware.
If you want to learn more about such practices and how you can build software for the future, feel free to follow us at GoTech 2021.