如何为 Spring WebFlux 配置 netty 连接超时

Ben*_*hey 5 reactor-netty spring-webflux spring-cloud-gateway

我在 AWS 负载均衡器后面运行 spring cloud gateway(我理解它是在 Spring Webflux 上构建的),并且我收到间歇性 502 错误。经过调查,问题似乎与负载均衡器和我的节点之间的连接超时有关。从一些调查来看,底层 netty 服务器的默认超时时间为 10 秒。我使用以下命令确定了这一点...

time nc -vv 10.10.xx.xxx 5100
Connection to 10.10.xx.xxx 5100 port [tcp/*] succeeded!

real    0m10.009s
user    0m0.000s
sys     0m0.000s
Run Code Online (Sandbox Code Playgroud)

虽然我可以将负载均衡器上的 idleTimeout 设置在 10 秒以内,但这感觉非常低效。如果可能,我想将其保持在 30 秒以上。相反,我想增加 netty 服务器上的连接超时。我试图在我的 application.yml 中设置 server.connection-timeout 属性...

server:
  connection-timeout: 75000
Run Code Online (Sandbox Code Playgroud)

也通过指定秒...

server:
  connection-timeout: 75s
Run Code Online (Sandbox Code Playgroud)

但是当我运行 time 命令以查看我的连接持续多长时间时,超时没有变化,它仍然以 10 秒结束......

time nc -vv 10.10.xx.xxx 5100
Connection to 10.10.xx.xxx 5100 port [tcp/*] succeeded!

real    0m10.009s
user    0m0.000s
sys     0m0.000s
Run Code Online (Sandbox Code Playgroud)

我在这里缺少什么?

Bri*_*zel 8

server.connection-timeout配置键不支持的Netty服务器(还),我已经提出了春天启动#15368修理好了。

连接超时大约是我们应该等待建立连接的最长时间。如果您想自定义读/写超时,那么这些是不同的选项。ReadTimeoutHandler如果服务器在配置的持续时间内没有从客户端接收数据,您可以添加关闭连接。与 a 相同WriteTimeoutHandler,但这次是关于服务器向客户端写入数据。

这是一个完整的例子:

@Configuration
public class ServerConfig {

    @Bean
    public WebServerFactoryCustomizer serverFactoryCustomizer() {
        return new NettyTimeoutCustomizer();
    }

    class NettyTimeoutCustomizer implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {

        @Override
        public void customize(NettyReactiveWebServerFactory factory) {
            int connectionTimeout = //...;
            int writetimeout = //...;
            factory.addServerCustomizers(server -> server.tcpConfiguration(tcp ->
                    tcp.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectionTimeout)
                            .doOnConnection(connection ->
                                    connection.addHandlerLast(new WriteTimeoutHandler(writetimeout)))));
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

现在回到您的问题,我已经使用以下控制器测试了该配置:

@RestController
public class TestController {

    @GetMapping(path = "/", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> textStream() {
        return Flux.interval(Duration.ofSeconds(5)).map(String::valueOf);
    }
}
Run Code Online (Sandbox Code Playgroud)

只要间隔小于配置的写入超时,服务器就不会关闭连接。您可以使用httpie和以下命令进行验证http localhost:8080/ --stream --timeout 60

我已经在我的本地机器上测试了这个 netcat 命令,到目前为止我没有超时。

time nc -vv 192.168.0.28 8080
192.168.0.28 8080 (http-alt) open
^CExiting.
Total received bytes: 0
Total sent bytes: 0
nc -vv 192.168.0.28 8080  0.01s user 0.00s system 0% cpu 2:36.53 total
Run Code Online (Sandbox Code Playgroud)

也许这是在操作系统级别配置的东西,或者网络设备配置为关闭此类连接?我刚刚看到您添加了 spring-cloud-gateway 标签 - 也许这是该项目特有的?