If we remember from Chapter 1, Why Reactive Spring?, the essence of reactive systems is in message-driven communication. Moreover, the previous chapters made it clear that by applying reactive programming techniques, we can write async interactions for interprocess/cross-service communication. In addition, by using the Reactive Streams specification, we are equipped to manage backpressure as well as failures in an asynchronous manner. Gathering all these features, we are capable of building a high-grained reactive application within one computer. Unfortunately, a one-node application has its constraints, which are expressed in hardware limitations. First of all, it is impossible to provide new computation resources such as additional CPU, RAM, and hard drive/SSD without shutting down the whole system. No benefit is gained from doing this, since users can be distributed over the world, so the overall user experience is different.
Such restrictions may be solved by splitting a monolithic application into microservices. The central idea of this technique is aimed at reaching an elastic system with straightforward location transparency. However, this way of building applications exposes a new horizon of problems, such as service management, monitoring, and painless scaling.