首页 > 解决方案 > reactor-netty TcpClient 连接池不释放连接

问题描述

使用 reactor-netty ConnectionProvider 连接不会释放到池中,因此不能重用,直到断开连接

我找到了一种解决方法:收到响应后断开连接,但这很糟糕,只有在我连接到同一网络中的邻居服务器时才适用

clientsMap.computeIfAbsent("$host:$port") { hostPort ->
    TcpClient.create(
            ConnectionProvider.builder(hostPort)
                    .maxConnections(maxConnections)
                    .pendingAcquireTimeout(Duration.ofSeconds(4))
                    .maxIdleTime(Duration.ofSeconds(10))
                    .build()
    )
            .host(host)
            .port(port)
            .observe { _, state -> println("state: $state") }
            //workaround as one packet is certainly less than 4096 bytes and the connection is stable enough
            .option(ChannelOption.RCVBUF_ALLOCATOR, FixedRecvByteBufAllocator(4096))
}.connect().flatMap { connection ->
    connection
            .outbound()
            .sendByteArray(Mono.just(send))
            .then()
            .thenMany(connection.inbound().receive().asByteArray())
            .takeUntil { it.size < 4096 }
            .map { it.toHexString() }
            .collect(Collectors.joining())
            .timeout(timeout)
            //the next line causes disconnecting after the response being read
            .doFinally { connection.channel().disconnect() }
}

请求数据时,输出为

state: [connected]
state: [configured]
state: [disconnecting]
state: [connected]
state: [configured]
state: [disconnecting]

但是这个解决方案比将连接返回到池并稍后重用它要糟糕得多

期望有一种connectionProvider.release(connection)方法强制将连接返回池,然后我会在doFinally中调用它,但没有那样的东西

如果我们注释 doFinally 调用,则state: [disconnecting]未写入,并且当远程主机获得超过 maxConnections 个连接并且尚未断开连接时,我们会捕获

Pool#acquire(Duration) has been pending for more than the configured timeout of 4000ms

经过测试的 reactor-netty 版本为 1.0.6 - 1.0.13

希望将连接返回到池并重新使用它而不是断开连接的解决方案

标签: javanettyreactor-netty

解决方案


推荐阅读