I have an application in Spring Boot RESTful service. My application does not have ideal throughput and causes the clients to get time-out in high volume concurrent requests. In that situation, the machine doesn't reach even 20% of its memory and CPU.
So, I decided to use reactive RESTful. Does making reactive controllers cause any improvement in throughput or is it necessary to make other internal methods like services and repositories reactive as well?
For instance, is it enough writing like following:
@GetMapping
private Flux<Employee> getAllEmployees() {
return employeeRepository.findAllEmployeesReqular();
}
Or is it necessary to write like this, where the internal method is reactive as well?
@GetMapping
private Flux<Employee> getAllEmployees() {
Flux<Employee> employees =employeeRepository.findAllEmployeesReactive();
return employees;
}
CodePudding user response:
Reactive and non-blocking generally do not make applications run faster. The expected benefit of reactive and non-blocking is the ability to scale the application with a small, fixed number of threads and lesser memory requirements. It makes applications more resilient under load because they scale in a more predictable manner.So, it is better to go with complete Reactive approach to make the API scalable and more resilient under load and can offer better results.
For more detailed explanation you can refer here too LINK.
CodePudding user response:
It is generally a good idea to have an application completely reactive.
In you first example the method getAllEmployees()
returns a Flux<Employee>
but calls a non-reactive, i.e. blocking method employeeRepository.findAllEmployeesReqular()
.
getAllEmployees()
will in no way behave reactive, because it is calling a potentially thread blocking repository.
A call to a method can only be reactive if all other methods downstream are also reactive.
If the downstream of your call consists of, say 12 methods, and only on of them blocks your thread, the whole call will block.
Will reactive applications run faster?
No, not automatically. If done right, reactive applications will always be responsive. They will not block. They will not block under load and they will not block under error (see https://www.reactivemanifesto.org). So they will probably feel faster, due to not blocking.
Additionally, you will in most cases recognize a higher CPU load, because reactive applications tend to make a better use of the CPU following the avoidance of blocking calls.
CodePudding user response:
A fully reactive solution is better than mixing them and, Spring has reactive repositories so you do not need to take care of that, only import the right library and that's it.
In you first example the method getAllEmployees() returns a Flux but calls a non-reactive, i.e. blocking method employeeRepository.findAllEmployeesReqular(). getAllEmployees() will in no way behave reactive, because it is calling a potentially thread blocking repository.
This is not all true, in your first example, you will get an error, a compiler one.
The right example would be:
@GetMapping
private Flux<Employee> getAllEmployees() {
return Flux.fromIterable(employeeRepository.findAllEmployeesReqular());
}
where you convert a list from a blocking execution to a Flux (you could use Flux.defer
, Flux.fromStream
too).