As compared to traditional applications, modern applications differ mainly in following ways:
- Distributed: Applications are distributed, i.e installed and running on huge number of machines simultaneously, like tens or even thousands.
- Data Size: Size of data being handled is much much huge(GBs vs PBs)
- Active Data: Earlier data usually was at rest, i.e not changing actively once pulled in by a batch job which runs like once in a day. Now data is changing rapidly and we need to keep up our data updated, else we are left behind and it's difficult to catch up.
- Zero Downtime: In past, applications downtime for maintenance or due to system crash were quite considerably high and acceptable. This is no more true. Users expect to access applications without delay.
- Fast Response: Modern applications are expected to respond lightning fast. Users have options available, and if applications don't meet their expectations they can very easily move to other options.
Reactive architecture is all about developing applications which are highly responsive, even under heavy load or even if some parts of the application are down. Goal is basically to develop a system which:
- Can be distributed over hundreds or even thousands of machines
- Scales from few to millions of users
- Continues to function even if there are failures
- Uses only resources required for current load
- Maintains satisfactory level of responsiveness even under heavy load or under failures
Reactive architecture is based on reactive principles, as described in reactive manifesto.
- Responsive: A reactive system is responsive, i.e it responds in a timely manner.
- Resilient: A reactive system remains responsive even when there are failures in the system. Means to achieve this are replication of components, containment of failures, isolation of failures, and delegation of tasks.
- Elastic(Scalable): A reactive system remains responsive even under varying loads. It means as load varies, system can increase or decrease the resources allocated to handle the requests. As a result, system doesn't have central bottlenecks or contention points.
- Message Driven: A reactive system makes use of asynchronous non-blocking message passing between different system components to establish a boundary between components that ensures loose coupling, isolation and location transparency. This also enables to communicate failures as messages.
Direction of arrows in above figure tells that being Responsive is facilitated by other three, being Elastic is made possible by being Message Driven and being Resilient, and being Resilient is made possible by being Message Driven and being Elastic.
Reactive programming is a programming technique which involves breaking a problem into small discrete steps and then executing those steps in asynchronous non-blocking manner, particularly using language specific techniques and APIs like Futures, Promises, CompletableFutures, Streams, RxJava, RxScala and several others. This is a way of ensuring that system resources like threads, CPU cycles etc. are not blocked.
But reactive programming is different from reactive architecture. Reactive architecture is used at architecture level to create systems or components, like reactive microservices, which follow reactive principles explained above. Merely implementing reactive programming does't mean that system follows reactive principles, though reactive programming tools and means can be used to built reactive systems.
Actor model
Actor model is a reactive programming paradigm which enables us to make reactive systems which follow reactive principles.
All communications between actors in actor model is based on asynchronous non-blocking messaging. And hence it automatically supports elastic and resilient aspects of a reactive system. Some additional facilities provided by actor model, like location transparency, makes it very easy to built highly responsive software systems.
On JVM, Akka toolkit is an implementation of actor model and it helps to build reactive systems. Based on it, additional reactive tools like Lagom and Akka streams are built.
Basic idea behind actor model is to compose the system of entities called Actors. An actor basically encapsulates state and behaviour, just like any other object on JVM. Difference is that actors communicate by sending asynchronous messages to each other rather than by method invocations. This asynchronous communication imparts location transparency to the actors. It means that actors communicate only through this mechanism irrespective of their location and local vs remote communication is merely about configuration. When an actor sends a message to another actor, it first goes to a router, which can also be an actor, and router then routes it to other actor. Other actor can be either residing on same JVM or some other JVM. From original actor's perspective, it has no knowledge of location of the actor which actually receives it and it doesn't even need to know it. Same API is used to send messages to actors, remote or local. This is what location transparency is all about. We just configure routers, and communication mechanism remains same. This makes actor system elastic and resilient. Now we can deploy actors on multiple machines easily. If one of the machine goes down, others are available to share the load, thus making system resilient. Also, if load goes up, we can easily deploy actors on new machines(or remove machines when load goes down), thus making system elastic.
Compared to other reactive programming tools like Rx, Futures,Promises, Streams etc, actor model provides support for all reactive principles. Other approaches support reactive system development partially, and hence we may need to add other tools and techniques like load balancing etc. Actor model, on other hand, supports asynchronous messaging, and being location transparent it enables system to be elastic and resilient. All these reactive principles then add responsiveness to the system. Though we can develop a system using actor model and still not reactive, but using it along with other tools based on it, developing a reactive system becomes much more easy.
We can built a reactive application without actor model. Like, we can make use of technologies like service registry, service discovery and load balancer to impart location transparency to our system. And then we can add something like a message bus to make asynchronous non-blocking messaging possible between components of the system. This all makes our system message driven, elastic and resilient and hence responsive. But as compared to actor model, these tools and techniques are not built-in, but rather added upon. This means we need additional infrastructure. Another difference is that with these tools we can make systems which are reactive at large scale, like at microservices level. But inside microservices, components may not be reactive. In case of actor model, actors residing inside microservices can be easily made reactive.
No comments:
Post a Comment