react-netty:使用保持活动状态的HTTP客户端

时间:2019-04-29 08:20:17

标签: java project-reactor reactor-netty

我使用wikibase:limit来请求一组URL。大多数URL属于同一主机。 reactor-netty似乎为每个URL建立了全新的TCP连接,即使已经为先前的URL建立了到主机的连接。建立数百个同时连接时,某些服务器会断开新连接或开始缓慢响应。

代码示例:

reactor-netty

在日志中,我看到同一远程主机的本地端口是不同的,活动连接和非活动连接的总和要比不同主机的数量高得多。这就是为什么我认为 Flux.just(...) .groupBy(link -> { String host = ""; try { host = new URL(link).getHost(); } catch (MalformedURLException e) { LOGGER.warn("Cannot determine host {}", link, e); } return host; }) .flatMap(group -> { HttpClient client = HttpClient.create() .keepAlive(true) .tcpConfiguration(tcp -> tcp.host(group.key())); return group.flatMap(link -> client.get() .uri(link) .response((resp, cont) -> resp.status().code() == 200 ? cont.aggregate().asString() : Mono.empty()) .doOnSubscribe(s -> LOGGER.debug("Requesting {}", link)) .timeout(Duration.ofMinutes(1)) .doOnError(e -> LOGGER.warn("Cannot get response from {}", link, e)) .onErrorResume(e -> Flux.empty()) .collect(Collectors.joining()) .filter(s -> StringUtils.isNotBlank(s))); }) .blockLast(); 不会重用已经建立的连接。

reactor-netty

是否可以使用DEBUG [2019-04-29 08:15:18,711] reactor-http-nio-10 r.n.r.PooledConnectionProvider: [id: 0xaed18e87, L:/192.168.1.183:56832 - R:capcp2.naad-adna.pelmorex.com/52.242.33.4:80] Releasing channel DEBUG [2019-04-29 08:15:18,711] reactor-http-nio-10 r.n.r.PooledConnectionProvider: [id: 0xaed18e87, L:/192.168.1.183:56832 - R:capcp2.naad-adna.pelmorex.com/52.242.33.4:80] Channel cleaned, now 1 active connections and 239 inactive connections ... DEBUG [2019-04-29 08:15:20,158] reactor-http-nio-10 r.n.r.PooledConnectionProvider: [id: 0xd6c6c5db, L:/192.168.1.183:56965 - R:capcp2.naad-adna.pelmorex.com/52.242.33.4:80] Releasing channel DEBUG [2019-04-29 08:15:20,158] reactor-http-nio-10 r.n.r.PooledConnectionProvider: [id: 0xd6c6c5db, L:/192.168.1.183:56965 - R:capcp2.naad-adna.pelmorex.com/52.242.33.4:80] Channel cleaned, now 0 active connections and 240 inactive connections HTTP客户端通过与主机的相同TCP连接在同一主机上请求多个URL?如果没有,如何限制到同一主机的同时连接数或按顺序执行到同一主机的请求(只有在收到对前一主机的响应之后才发出下一个请求)?

我使用keep-alive发行火车。

1 个答案:

答案 0 :(得分:1)

是的,reactor netty支持保持活动,连接重用和连接池。

请注意,.flatMap是异步处理,用于并行处理内部流。因此,当您调用group.flatMap(...时,内部请求将并行执行。并且由于它们是并行执行的,因此需要建立多个连接。

如果要顺序执行对同一主机的请求,请将示例更改为使用group.concatMap而不是.flatMap

如果您仍然希望并行执行它们,但将活动请求的数量限制为单个主机,则更改示例以使用.flatMap的重载版本之一,该版本需要一个concurrency参数。

此外,由于您使用的是HttpClient.create(),因此您的示例使用默认的全局http连接池。如果要进一步控制连接池,可以通过HttpClient.create(ConnectionProvider)指定其他ConnectionProvider