我们在netty-3.6运行的后端使用haproxy.我们正在处理大量的连接,其中一些可能是长期的.
现在的问题是,当haproxy关闭连接以实现重新平衡时,它会通过发送tcp-RST来实现.当netty使用的sun.nio.ch-class看到这个时,它会抛出一个IOException:"Connection by peer".
跟踪:
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 ""
Run Code Online (Sandbox Code Playgroud)
这会导致每个配置出现以下问题:
选项http-pretend-keepalive
这是最好的(因为haproxy似乎关闭了大多数与FIN而不是RST的连接),但仍然每秒每服务器产生大约3个异常.此外,它实际上是neuters负载平衡,因为一些传入连接非常长,并且具有非常高的吞吐量:使用pretend-keepalive,它们永远不会被haproxy重新平衡到另一台服务器.
选项http-keep-alive
由于我们的后端期望保持活动连接真正保持活动(因此不会自行关闭它们),因此此设置相当于每个连接最终会导致一个异常,从而导致我们的服务器崩溃.我们尝试添加prefer-last-server,但它没有多大帮助.
选项http-server-close
从理论上讲,这应该适用于正确的负载均衡和无异常.但是,似乎在我们的后端服务器响应后,有一个竞争对手首先发送其RST:haproxy或我们注册的ChannelFutureListener.CLOSE.在实践中,我们仍然会遇到太多异常,我们的服务器崩溃了.
有趣的是,例外情况通常越多,我们为渠道提供的工人越多.我想它的阅读速度超过了写作速度.
无论如何,我已经阅读了netty中的不同频道和套接字以及haproxy一段时间了,并没有真正找到任何听起来像解决方案的东西(或者当我尝试它时工作).