Haproxy + netty: способ предотвращения исключений при сбросе соединения?

Мы'использовать haproxy перед нет-3,6-бэк-бэкэндом. Мы работаем с огромным количеством соединений, некоторые из которых могут быть давними.

Теперь проблема в том, что, когда haproxy закрывает соединение для восстановления баланса, оно делает это, отправляя tcp-RST. Когда класс sun.nio.ch, используемый netty, видит это, он генерирует IOException: "Сброс соединения по пиру ".

Трассировка:

sun.nio.ch.FileDispatcherImpl.read0(Native Method):1 in ""
sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39):1 in ""
sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:225):1 in ""
sun.nio.ch.IOUtil.read(IOUtil.java:193):1 in ""
sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:375):1 in ""
org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:64):1 in ""
org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:109):1 in ""
org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:312):1 in ""
org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:90):1 in ""
org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178):1 in ""
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145):1 in ""
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615):1 in ""
java.lang.Thread.run(Thread.java:724):1 in ""

Это вызывает следующие проблемы для каждой конфигурации:

опция http-pretend-keepalive

Это то, что работает лучше всего (поскольку haproxy, по-видимому, закрывает большинство соединений с помощью FIN, а не RST), но все равно выдает около 3 исключений на сервер в секунду. Кроме того, он эффективно нейтрализует балансировку нагрузки, поскольку некоторые входящие соединения очень продолжительны и имеют очень высокую пропускную способность: с помощью pretend-keepalive они никогда не перебалансируются на другой сервер с помощью haproxy.

опция http-keep-alive

Поскольку наш бэкэнд ожидает, что соединения keep-alive действительно будут поддерживаться (и, следовательно, не будут закрывать их сами по себе), этот параметр равняется каждому соединению, в конечном итоге приводящему к одному исключению, что, в свою очередь, приводит к сбою наших серверов. Мы попытались добавить предпочитаемый-последний-сервер, но это нене очень помогает.

опция http-server-close

Теоретически это должно работать как для правильной балансировки нагрузки, так и без исключений. Однако, похоже, что после ответа наших backend-серверов возникает гонка относительно того, какая сторона отправляет свой RST в первую очередь: haproxy или наш зарегистрированный ChannelFutureListener.CLOSE. На практике мы все еще получаем слишком много исключений, и наши серверы аварийно завершают работу.

Интересно, что, как правило, исключений становится больше, чем больше работников мы снабжаем нашими каналами. Я предполагаю, что это ускоряет чтение больше, чем письмо.

В любом случае, ямы читали о различных каналах и сокетах в netty и haproxy некоторое время и не делалина самом деле не найти ничего, что звучало бы как решение (или сработало, когда я попробовал).

Ответы на вопрос(5)

Ваш ответ на вопрос