Как настроить время ожидания соединения Netty для Spring WebFlux - PullRequest
0 голосов
/ 03 декабря 2018

Я использую Spring Cloud Gateway (который, как я понимаю, построен на Spring Webflux) за балансировщиком нагрузки AWS, и я получаю периодические ошибки 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

Хотя я мог просто положить idleTimeout на балансировщик нагрузки на что-то меньше 10 секунд, это кажется очень неэффективным.Я хотел бы держать его выше 30 секунд, если это возможно.Вместо этого я хотел бы увеличить время ожидания соединения на сервере netty.Я попытался установить свойство server.connection-timeout в моем application.yml ...

server:
  connection-timeout: 75000

также, указав секунды ...

server:
  connection-timeout: 75s

Но это не имелоизмените тайм-аут, когда я запускаю команду времени, чтобы посмотреть, как долго длится мое соединение, оно все еще заканчивается через 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

Чего мне здесь не хватает?

1 Ответ

0 голосов
/ 03 декабря 2018

Ключ конфигурации server.connection-timeout не поддерживается для серверов Netty (пока), я поднял spring-boot # 15368 , чтобы исправить это.

Время ожидания соединения составляет околомаксимальное количество времени, которое мы должны ждать для установления соединения.Если вы хотите настроить таймауты чтения / записи, это разные варианты.Вы можете добавить ReadTimeoutHandler, который закрывает соединение, если сервер не получает данные от клиента в течение заданного времени.То же самое с 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 - может быть, это что-то особенное для этого проекта?

...