spring-webflux - 如何为 Spring WebFlux 配置 netty 连接超时
问题描述
我在 AWS 负载均衡器后面运行 spring 云网关(我理解它是在 Spring Webflux 上构建的),我收到间歇性的 502 错误。经调查,问题似乎与负载均衡器和我的节点之间的连接超时有关。从一些调查看来,底层网络服务器的默认超时时间为 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
虽然我可以将负载均衡器上的 idleTimeout 设置为 10 秒以下,但感觉效率非常低。如果可能的话,我想保持在 30 秒以上。相反,我想增加 netty 服务器上的连接超时。我试图在我的 application.yml 中设置 server.connection-timeout 属性...
server:
connection-timeout: 75000
也通过指定秒...
server:
connection-timeout: 75s
但是,当我运行 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
我在这里想念什么?
解决方案
Netty 服务器(尚)不支持配置键,server.connection-timeout
我提出了spring-boot#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)))));
}
}
}
现在回到您的问题,我已经使用以下控制器测试了该配置:
@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
。
我已经在我的本地机器上测试了这个 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
也许这是在操作系统级别配置的东西,或者网络设备被配置为关闭此类连接?我刚刚看到您添加了 spring-cloud-gateway 标签 - 也许这是该项目特有的东西?
推荐阅读
- javascript - 如何使用 css 关键帧同步两个动画?
- c++ - 回到行首的新行转义序列
- reactjs - 我如何分享从 React Native 到 Instagram 的视频?
- javascript - Javascript:文件构造函数的参数 1 不能转换为序列
- linux - 识别在 linux 中运行超过 3 小时的进程
- python - 并行调用函数内的多个函数
- mongodb - 本地 Docker Compose 在运行命令时异常退出,代码为 1:up -d
- python - 如何在 Python NetworkX 中编写与 R igraph 相同的代码
- django - Django QuerySet 评估通过 [] 访问元素
- apache-kafka - Kakfa 2.4 中的 TopicCommand.alterTopic