set timeout in Spring WebFlux webclient set timeout in Spring WebFlux webclient spring spring

set timeout in Spring WebFlux webclient


I've tried reproducing the issue and couldn't. Using reactor-netty 0.7.5.RELEASE.

I'm not sure about which timeout you're talking about.

Connection timeout can be configured with ChannelOption.CONNECT_TIMEOUT_MILLIS. I'm getting 10 seconds between the "connecting" log message and the actual error:

WebClient webClient = WebClient.builder()    .clientConnector(new ReactorClientHttpConnector(options -> options        .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)))    .build();webClient.get().uri("http://10.0.0.1/resource").exchange()    .doOnSubscribe(subscription -> logger.info("connecting"))    .then()    .doOnError(err -> logger.severe(err.getMessage()))    .block();

If you're talking about read/write timeouts, then you can look at Netty's ReadTimeoutHandler and WriteTimeoutHandler.

A full example could look like this:

ReactorClientHttpConnector connector = new ReactorClientHttpConnector(options ->        options.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10)                .onChannelInit(channel -> {                        channel.pipeline().addLast(new ReadTimeoutHandler(10))                                .addLast(new WriteTimeoutHandler(10));                return true;        }).build());

As of Reactor Netty 0.8 and Spring Framework 5.1, the configuration now looks like this:

TcpClient tcpClient = TcpClient.create()                 .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000)                 .doOnConnected(connection ->                         connection.addHandlerLast(new ReadTimeoutHandler(10))                                   .addHandlerLast(new WriteTimeoutHandler(10)));WebClient webClient = WebClient.builder()    .clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient)))    .build();

Maybe adding the following to your application.properties will provide more information on what's happening at the HTTP level:

logging.level.reactor.ipc.netty.channel.ContextHandler=debuglogging.level.reactor.ipc.netty.http.client.HttpClient=debug


Since HttpClient.from(tcpClient) is now deprecated in the latest netty (v0.9.x and will be removed in v1.1.0). You can use responseTimeout() and ignore too many HTTP connection configurations which you see in other code and this implementation works with the old as well as the new one.

Create HttpClient

HttpClient httpClient = HttpClient.create().responseTimeout(Duration.ofMillis(500)); // 500 -> timeout in millis

Add httpClient to webclient using webClient builder fxn .clientConnector()

WebClient.builder().baseUrl("http://myawesomeurl.com").clientConnector(new ReactorClientHttpConnector(httpClient)).build();

Also, the majority of the implementation available over the website is not deprecated to make sure that you are not using the deprecated one you can check out this link.

FYI: For the older netty versions (i.e < v0.9.11 version) responseTimeout() uses tcpConfiguration() under the hood, which is deprecated in the new versions. But responseTimeout() uses the new implementation in >=v0.9.11, so even if you change the netty version of your project in the future your code is not going to break.

NOTE: If you are using the old netty version which comes by default with spring sometimes, you probably can use Brian's implementation too. (Not sure though)

If you want to read more about responseTimeout() and how does it work, you can check the source code here and here or the github gist here.


Per HttpClient.from(TcpClient) method, as @im_bhatman mentioned, has been deprecated, here comes a way using the good-old way.

// works for Spring Boot 2.4.0, 2.4.1, and 2.4.2// doesn't work for Spring Boot 2.3.6, 2.3.7, and 2.3.8HttpClient httpClient = HttpClient.create()        //.responseTimeout(Duration.ofSeconds(READ_TIMEOUT_SECONDS))        .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONNECT_TIME_MILLIS)        .doOnConnected(c -> {                c.addHandlerLast(new ReadTimeoutHandler(READ_TIMEOUT_SECONDS))                 .addHandlerLast(new WriteTimeoutHandler(WRITE_TIMEOUT_SECONDS));        });ClientConnector clientConnector = new ReactorClientHttpConnector(httpClient);WebClient webClient = WebClient.builder()        .clientConnector(clientConnector)        ...        .build();

I'm not sure about the difference of

  • HttpClient#responseTimeout(...)
  • HttpClient#doOnConnected(c -> c.addHandler(new ReadTimeoutHandler(...)))