如何为Spring WebFlux配置Netty连接超时 [英] How to configure netty connection-timeout for Spring WebFlux

查看:1189
本文介绍了如何为Spring WebFlux配置Netty连接超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am running spring cloud gateway (which I understand to be built on Spring Webflux) behind an AWS loadbalancer and I am receiving intermittent 502 errors. Upon investigation, it appears the issue has to do with connection timeouts between the loadbalancer and my nodes. From some investigation it appears that the underlying netty server has a default timeout of 10 seconds. I determined this using the following command...

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

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

While I could just put the idleTimeout on the load balancer to something under 10 seconds, that feels very inefficient. I would like to keep it above 30 seconds if possible. Instead I would like to increase the connection timeout on the netty server. I have attempted to set the server.connection-timeout property in my application.yml...

server:
  connection-timeout: 75000

还通过指定秒数...

also by specifying seconds...

server:
  connection-timeout: 75s

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

But this has had no change on the timeout when I run the time command to see how long my connection lasts, it still ends at 10 seconds...

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

我在这里想念什么?

推荐答案

Netty服务器尚不支持server.connection-timeout配置密钥,但我提出了

The server.connection-timeout configuration key is not supported for Netty servers (yet), I've raised spring-boot#15368 to fix that.

连接超时大约是我们应该等待建立连接的最长时间.如果您要自定义读取/写入超时,则可以选择这些选项.如果服务器在配置的持续时间内未从客户端接收数据,则可以添加ReadTimeoutHandler来关闭连接. WriteTimeoutHandler也是一样,但是这次是服务器将数据写入客户端.

The connection timeout is about the maximum amount of time we should wait to for a connection to be established. If you're looking to customize the read/write timeouts, those are different options. You can add a ReadTimeoutHandler that closes the connection if the server doesn't receive data from the client in the configured duration. Same thing with a WriteTimeoutHandler, but this time about the server writing data to the client.

这是一个完整的示例:

@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)))));
        }
    }

}

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

Back to your question now, I've tested that configuration with the following controller:

@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);
    }
}

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

As long as the interval is shorter than the configured write timeout, the connection is not closed by the server. You can verify that with httpie and the following command http localhost:8080/ --stream --timeout 60.

我已经在本地计算机上测试了该netcat命令,并且到目前为止没有超时.

I've tested this netcat command on my local machine and I'm hitting no timeout so far.

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

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

Maybe this is something configured at the OS level, or maybe a network appliance is configured to close such connections? I just saw that you added the spring-cloud-gateway label - maybe this is something specific to that project?

这篇关于如何为Spring WebFlux配置Netty连接超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆