by example
https://github.com/idugalic/reactive-company
is about non-blocking applications that are:
- asynchronous
- message-driven
- require a small number of threads to scale vertically
- use back-pressure
+++
Asynchronous
- Processing of a request occurs at an arbitrary point in time, sometime after it has been transmitted from client to service.
- Asynchronous IO refers to an interface where you supply a callback to an IO operation, which is invoked when the operation completes.
+++
Non-blocking
- In concurrent programming an algorithm is considered non-blocking if threads competing for a resource do not have their execution indefinitely postponed by mutual exclusion protecting that resource.
- Non-blocking IO refers to an interface where IO operations will return immediately with a special error code if called when they are in a state that would otherwise cause them to block.
+++
Message-driven
- Event-driven system focuses on addressable event sources while a message-driven system concentrates on addressable recipients.
- Resilience is more difficult to achieve in an event-driven system.
+++
Back-pressure
- Back-pressure is an important feedback mechanism that allows systems to gracefully respond to load rather than collapse under it.
- A mechanism to ensure producers don’t overwhelm consumers.
- One component in the chain will communicate the fact that it is under stress to upstream components and so get them to reduce the load.
+++
Service
@GetMapping("/blogposts")
Flux<BlogPost> list() {
LOG.info("Received request: BlogPost - List");
try {
return this.blogPostRepository.findAll().log();
} finally {
LOG.info("Request pocessed: BlogPost - List");
}
}
+++
Log
A possible log output we could see is:
As we can see the output of the controller method is evaluated after its execution in a different thread too!
+++
Summary
- We can no longer think in terms of a linear execution model where one request is handled by one thread
- The reactive streams will be handled by a lot of threads in their lifecycle
- We no longer can rely on thread affinity for things like the security context or transaction handling
are:
- responsive
- resilient
- elastic
- message driven
+++
Responsive
- The system responds in a timely manner if at all possible.
+++
Resilient
- The system stays responsive in the face of failure.
+++
Elastic
- The system stays responsive under varying workload.
+++
Message Driven
- Reactive Systems rely on asynchronous message-passing to establish a boundary between components that ensures loose coupling, isolation and location transparency.
+++
Summary
- Reactive programming offers productivity for developers—through performance and resource efficiency—at the component level for internal logic and dataflow transformation
- Reactive systems offer productivity for architects and DevOps practitioners—through resilience and elasticity—at the system level
The promise of Reactive is that you can do more with less, specifically you can process higher loads with fewer threads.
- For the right problem, the effects are dramatic
- For the wrong problem, the effects might go into reverse (you actually make things worse)
Is your web application responsive? There is only one way to know this: test your web application!
$ ./mvnw gatling:execute