我正在使用Spring WebFlux WebClient从我的Spring Boot应用程序中进行休息调用。每次在30秒内获得超时。
这是我尝试在Spring Webfulx的Webclient中设置套接字超时的一些代码。
- 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));
}));
并尝试通过使用"客户端连接"方法在" WebClient"中添加以上连接器设置。
,还尝试将超时设置如下:
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));
上述选项都不适合我。
我正在使用org.springframework.boot:spring-boot-gradle-plugin:2.0.0.m7,在内部具有org.springframework:spring-webflux:5.0.2.release:5.0.2.release。
请在这里建议,让我知道我在这里是否做错了。
我尝试过重现问题,但不能。使用反应器netty 0.7.5.Release。
我不确定您在谈论哪个超时。
可以使用ChannelOption.CONNECT_TIMEOUT_MILLIS
配置连接超时。我在"连接"日志消息和实际错误之间获得了10秒:
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();
如果您要谈论的是阅读/写入超时,则可以查看Netty的ReadTimeoutHandler
和WriteTimeoutHandler
。
一个完整的例子看起来像这样:
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());
从反应堆Netty 0.8和Spring Framework 5.1开始,该配置现在看起来像:
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();
也许将以下内容添加到您的application.properties
将提供有关HTTP级别发生的情况的更多信息:
logging.level.reactor.ipc.netty.channel.ContextHandler=debug
logging.level.reactor.ipc.netty.http.client.HttpClient=debug
,因为HttpClient.from(tcpClient)
现在已在最新的Netty中弃用(v0.9.x,并将在v1.1.0中删除(。您可以使用responseTimeout()
,而忽略太多的HTTP连接配置,您在其他代码中看到这些配置,并且此实现与旧代码以及新代码一起工作。
创建httpclient
HttpClient httpClient = HttpClient.create().responseTimeout(Duration.ofMillis(500)); // 500 -> timeout in millis
使用WebClient Builder FXN .clientConnector()
WebClient
.builder()
.baseUrl("http://myawesomeurl.com")
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();
此外,网站上可用的大多数实施不推荐,以确保您不使用不弃用的链接,您可以查看此链接。
fyi:对于较旧的Netty版本(即< v0.9.11版本(responseTimeout()
在引擎盖下使用tcpconfiguration((,在新版本中被弃用。但是ResponsEtion Out((在> = v0.9.11中使用新实现,因此,即使您将来更改项目的Netty版本,您的代码也不会破坏。
注意:如果您使用的是默认情况下的旧Netty版本,有时还可以使用Brian的实现。(虽然不确定(
如果您想阅读有关ResponseTion out((的更多信息以及如何工作,则可以在此处和此处检查源代码或此处的GitHub Gist。
按HttpClient.from(TcpClient)
方法@IM_BHATMAN提到,已弃用,这是一种使用良好的方式。
// 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.8
HttpClient 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();
我不确定
的差异-
HttpClient#responseTimeout(...)
-
HttpClient#doOnConnected(c -> c.addHandler(new ReadTimeoutHandler(...)))
请参阅下面的代码块,以使用WebClient
设置超时和重试.retrieve()
.onStatus(
(HttpStatus::isError), // or the code that you want
(it -> handleError(it.statusCode().getReasonPhrase())) //handling error request
)
.bodyToMono(String.class)
.timeout(Duration.ofSeconds(5))
.retryWhen(
Retry.backoff(retryCount, Duration.ofSeconds(5))
.filter(throwable -> throwable instanceof TimeoutException)
)