Issue
I wanted to probe the reactive REST client from Quarkus for slow backends and did some load testing on their suggested sample (https://github.com/quarkusio/quarkus-quickstarts/tree/main/rest-client-reactive-quickstart) with just some minor modifications. I have the following dependencies in my build.gradle with the Quarkus version set to 2.11.3.Final:
dependencies {
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
implementation 'io.quarkus:quarkus-rest-client-reactive'
implementation 'io.quarkus:quarkus-resteasy-reactive'
implementation 'io.quarkus:quarkus-arc'
testImplementation 'io.quarkus:quarkus-junit5'
testImplementation 'io.rest-assured:rest-assured'
}
I wanted to check the behavior for a slow answering backend with two variants
- Creating a new Uni and delaying its emission
- Calling a locally running go server that does nothing more than waiting one second to respond (can be found here: https://gist.github.com/s-macke/c3b1d0029ef61efc7ed2d22a4132cad2)
My resource and client calling the backend look as follows:
@Path("/reactive")
public class ReactiveResource {
@RestClient
TimeoutTestService service;
@GET
@Path("delay")
@Produces(MediaType.TEXT_PLAIN)
public Uni<String> reactiveThreadTimeout() {
return Uni.createFrom().item("Hello RESTEasy")
.onItem().delayIt().by(Duration.of(1, ChronoUnit.SECONDS));
}
@GET
@Path("remote")
@Produces(MediaType.TEXT_PLAIN)
public Uni<String> reactiveRemoteTimeout() {
return service.testTimeoutReactive();
}
}
@RegisterRestClient(baseUri = "http://localhost:8500")
@Produces(MediaType.TEXT_PLAIN)
public interface TimeoutTestService {
@GET
@Path("/reactive")
Uni<String> testTimeoutReactive();
}
With a load test I had no problems with the first variant with all requests being answered in 1 second even with 300 requests per second. In the second variant it worked perfectly with 20 rps but with more load response times slowly increased as if something was blocking the calling threads. I can rule out the go server as this can handle the 300 rps without problems when calling it directly. Maybe the problems are due to both Quarkus and the go server running on my local machine but I still would have expected better results with the reactive client. Did anyone else observe similar problems when using the reactive client with more than basic load?
Solution
You're running into https://github.com/quarkusio/quarkus/issues/21884. It may seem unexpected, but the client has a connection pool with default size of 20. If you want to allow more concurrent requests than 20, you can reconfigure it:
quarkus.rest-client."com.example.TimeoutTestService".connection-pool-size=100
Answered By - Ladicek
Answer Checked By - Senaida (JavaFixing Volunteer)