I'm using Spring Webflux WebClient to make a REST call from my Spring boot application. And every time getting a timeout in 30 seconds.
Here is some code I tried to set socket timeout in WebClient of Spring webfulx.
- ReactorClientHttpConnector connector = new ReactorClientHttpConnector(options -> options
.option(ChannelOption.SO_TIMEOUT, 600000).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 600000));
- ReactorClientHttpConnector connector = new ReactorClientHttpConnector(
options -> options.afterChannelInit(chan -> {
chan.pipeline().addLast(new ReadTimeoutHandler(600000));
}));
- ReactorClientHttpConnector connector1 = new ReactorClientHttpConnector(options -> options
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 600000).afterNettyContextInit(ctx -> {
ctx.addHandlerLast(new ReadTimeoutHandler(600000, TimeUnit.MILLISECONDS));
}));
And tried to add this above connector setting in “WebClient” by using “clientConnector” method.
And also tried to set timeout as below:
webClient.get().uri(builder -> builder.path("/result/{name}/sets")
.queryParam("q", "kind:RECORDS")
.queryParam("offset", offset)
.queryParam("limit", RECORD_COUNT_LIMIT)
.build(name))
.header(HttpHeaders.AUTHORIZATION, accessToken)
.exchange().timeout(Duration.ofMillis(600000))
.flatMap(response -> handleResponse(response, name, offset));
None of the above options is working for me.
I'm using org.springframework.boot:spring-boot-gradle-plugin:2.0.0.M7 which interally have dependecy of org.springframework:spring-webflux:5.0.2.RELEASE.
Please suggest here and let me know if I'm doing anything wrong here.
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=debug
logging.level.reactor.ipc.netty.http.client.HttpClient=debug