Make a project with the dependency spring-boot-starter-webflux. Add the following simple test:

@SpringBootTest
class SlowWebClientTest {
    @Autowired
    WebClient.Builder builder;

    @Test
    void getRequest() {
        var client = builder.build();
        var body = client.get()
                .uri("https://reqres.in/api/users/1")
                .retrieve()
                .toBodilessEntity();
        StepVerifier.create(body).expectNextCount(1).verifyComplete();
    }
}
````

- With Spring Boot 2.4.0 it takes over **7.5 seconds** to run this test.
- With Spring Boot 2.3.6.RELEASE  it takes **under 2.5 seconds**  to run this test.

I ran the test multiple times with both versions of Spring Boot.

**Comment From: wilkinsona**

Thanks for the report. Unfortunately, I can't reproduce the behaviour that you have described. I ran the test above 10 times with Spring Boot 2.3.6.RELEASE and with 2.4.0. The execution time of the tests as reported by Eclipse was the following:

2.3.6 | 2.4.0
----- | -----
0.902 | 0.960
0.929 | 0.935
0.915 | 0.936
1.426 | 0.987
1.390 | 1.051
0.892 | 1.473
0.920 | 0.944
0.927 | 1.231
0.889 | 0.989
0.935 | 1.251

The average time was 1.013 with 2.3.6 and 1.076 with 2.4.0. Given the variation in the execution times, these averages are essentially the same.

I also tried a modified version of your test that uses Spring Boot purely for dependency management:

```java
package com.example.gh24210;

import org.junit.jupiter.api.Test;
import org.springframework.http.ResponseEntity;
import org.springframework.web.reactive.function.client.WebClient;

import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;

class SlowWebClientTest {

    private final WebClient.Builder builder = WebClient.builder();

    @Test
    void getRequest() {
        WebClient client = builder.build();
        Mono<ResponseEntity<Void>> body = client.get()
                .uri("https://reqres.in/api/users/1")
                .retrieve()
                .toBodilessEntity();
        StepVerifier.create(body).expectNextCount(1).verifyComplete();
    }

}

Timing the test in Eclipse again gave the following results:

2.3.6 2.4.0
1.307 1.284
1.206 1.269
1.397 1.496
1.626 1.291
1.487 1.269
1.376 1.293
1.211 1.280
1.198 1.307
1.191 1.337
1.186 1.315

Each test is taking slightly longer as more work is being done within the test itself (creation of the WebClient.Builder). The average time was 1.319 with 2.3.6 and 1.314 with 2.4.0. Once again, given the variation in execution time, these averages are essentially the same.

It looks to me like the problem may be specific to your environment. If you'd like us to spend some more time investigating we'll need to be able to reproduce the problem. Perhaps you could help to narrow things down a bit? For example, you could try the modified test above which doesn't involve Spring Boot while the test is executing. It'll also produce more log output which may help to identify what's causing the 5 second delay in your case. You could also try running you original test with some debug logging enabled to see if the delay is apparent in the output.

Comment From: dreis2211

If that helps, I can confirm @hansdesmet's timings when running the tests with IntelliJ. I wonder if that's the case here and if execution via command line shows the same difference. For me it shows normal timings on the command line, for example.

Comment From: hansdesmet

I run this test in IntelliJ 2020.2.3 on Windows 10 Pro version 20H2. I'v run the test on the same OS in Eclipse en Netbeans, with the same result. Andy, are you running on anohter OS ?

Comment From: bclozel

See https://github.com/reactor/reactor-netty/issues/560#issuecomment-728908781

Comment From: hansdesmet

I use Java version 11.0.7, from AdoptOpenJDK.

Comment From: bclozel

@hansdesmet do you have the openssl native libraries installed? Can you check whether manually loading those libraries (something like System.out.println(OpenSsl.version());, see Violeta's comment changes things?

Comment From: hansdesmet

OpenSsl.version() gives -1

Comment From: wilkinsona

I ran the tests on macOS (10.15.5) using Java 11.0.7 from AdoptOpenJDK.

Comment From: violetagg

@hansdesmet I tested on a VM with Windows 10, IntelliJ IDEA 2020.2.3 and adopt-openjdk-11.0.9.1 and I also do not see difference between 2.3.6 and 2.4.0

Can you try to run with this property -Dio.netty.handler.ssl.noOpenSsl=true as you do not have OpenSSL on your system?

Comment From: hansdesmet

Hi Violeta, I'v tried with -Dio.netty.handler.ssl.noOpenSsl=true. The results are the same.

Comment From: hansdesmet

I was wondering if HTTPS requests caused the problem (SSL and friends ...) So I changed the code so that it does a request to a HTTP resource: http://dummy.restapiexample.com/api/v1/employee/3 But the results are the same: 2.4.0: 9 seconds, 2.3.6: 2.5 seconds

Comment From: wilkinsona

@hansdesmet Can you please try the two experiments I suggested above:

  1. The modified test that removes Spring Boot from the picture at runtime
  2. The original test with debug logging enabled

Comparing the timings and output of both with 2.3.6 and 2.4.0 may help to shed some light on the point at which the delay is occurring.

Comment From: hansdesmet

Hi Andy

In my Spring Boot application, i added following lines to application.properties: logging.level.org.springframework.web.reactive=DEBUG logging.level.io.netty=DEBUG

The logging of Spring Boot 2.3.6: 2-3-6-log.txt

The logging of Spring Boot 2.4.0: 2-4-0-log.txt

Comment From: wilkinsona

Thanks. It looks like a DNS-related problem to me. I see the following in the logs for 2.4.0:

2020-11-20 12:17:42.872 DEBUG 21032 --- [ctor-http-nio-1] io.netty.resolver.dns.DnsQueryContext    : [id: 0xe36d83d0] WRITE: UDP, [25358: /10.123.173.11:53], DefaultDnsQuestion(dummy.restapiexample.com. IN AAAA)
2020-11-20 12:17:47.886 DEBUG 21032 --- [ctor-http-nio-1] io.netty.resolver.dns.DnsQueryContext    : [id: 0xe36d83d0] WRITE: UDP, [51691: /8.8.8.8:53], DefaultDnsQuestion(dummy.restapiexample.com. IN A)

Note the 5 second gap between the two log messages.

Comment From: dreis2211

I wonder if that's connected to https://github.com/reactor/reactor-netty/pull/1252

Comment From: violetagg

@dreis2211 @hansdesmet There is change between 2.3.6 which runs with the default jdk dns resolver and 2.4.0 which uses the Netty's one, but still this does not explain why it is reproducible on @hansdesmet system or why in your case @dreis2211 it is reproducible only from IDE and not from the command line

Comment From: dreis2211

@violetagg I can't reproduce anymore, unfortunately. Neither in IDE nor from command line on my Mac. I even cleared the DNS cache to rule that one out. I guess we're left with @hansdesmet's case.

Comment From: violetagg

Can you try the following configuration for DNS resolver

class SlowWebClientTest {

    private final WebClient.Builder builder = WebClient.builder();

    @Test
    void getRequest() {
        HttpClient httpClient = HttpClient.create()
                .compress(true)
                .resolver(spec -> spec.queryTimeout(Duration.ofMillis(500)).trace("DNS", LogLevel.DEBUG));

        WebClient client = builder.clientConnector(new ReactorClientHttpConnector(httpClient)).build();
        Mono<ResponseEntity<Void>> body = client.get()
                .uri("https://reqres.in/api/users/1")
                .retrieve()
                .toBodilessEntity();
        StepVerifier.create(body).expectNextCount(1).verifyComplete();
    }

}

query timeout by default is 5s, the configuration above sets this to 500ms https://projectreactor.io/docs/netty/release/api/reactor/netty/transport/NameResolverProvider.NameResolverSpec.html#queryTimeout-java.time.Duration-

the configuration also enables tracing for failed queries https://projectreactor.io/docs/netty/release/api/reactor/netty/transport/NameResolverProvider.NameResolverSpec.html#trace-java.lang.String-io.netty.handler.logging.LogLevel-

Comment From: hansdesmet

Hi Violeta

I changed the code like you suggested. Now the code takes less time (3.4 seconds) on 2.4.0, but still more than the original code on 2.3.6 (2.5 seconds).

The log output: violetalog.txt

I can't run the new code on 2.3.6: it complains that the method resolver does not exist on HttpClient.

Comment From: violetagg

@hansdesmet Can you try just for testing purposes to use JDK 8?

Comment From: violetagg

also this logger "DNS" should be with level debug if we want to see the traces for the failed queries

logging.level.DNS=debug

Comment From: hansdesmet

Hi Violeta I added logging.level.DNS=debug to application.properties

This is the logging output with Java 11: logOutputWithJava11.txt

This is the logging output with Java 8: logOutputWithJava8.txt The code takes the same time to run on Java 8 as on Java 11.

Comment From: hansdesmet

Hi Violeta I have run the same code on a Virtual Windows 10 PC on Azure, using Java 11.0.8 The code takes about 4.3 seconds to run. The logging ouput: logOutputOnAzureWithJava11.txt

Comment From: violetagg

Hi Violeta I have run the same code on a Virtual Windows 10 PC on Azure, using Java 11.0.8 The code takes about 4.3 seconds to run. The logging ouput: logOutputOnAzureWithJava11.txt

This one does not seem to be affected by a non responding DNS server as in the previous comment https://github.com/spring-projects/spring-boot/issues/24210#issuecomment-731991724

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: violetagg

@hansdesmet While investigating this either remove this non responding server from the lists with the DNS servers or use this resolver HttpClient.resolver(DefaultAddressResolverGroup.INSTANCE) @wilkinsona I think this should be Reactor Netty issue.

Comment From: wilkinsona

Thanks, @violetagg. Unfortunately, we can't transfer the issue but I'll close this one in any case. @hansdesmet please open a Reactor Netty issue so that we can continue to track the problem you're seeing.