情况:我有一个代理应用程序,使用的是Netty 4.0.17.Final(FYI:我已经遇到了版本4.0.13.Final和4.0.9.Final的问题),并且基于来自Netty示例的代理。
我的代码与示例之间的主要区别在于,当通道激活时,我的代码不会连接到后端服务器,而是只有在第一次读取时才会连接,因为这个读取必须先对输入进行一些检查,然后才能连接并将该消息转发到后端服务器。
我已经为我的应用程序进行了单元测试和负载测试,运行时间长达数小时,并且一切运作良好。
问题:由于需要执行一些阻塞操作,因此尝试为执行此操作的处理程序使用单独的EventExecutorGroup
(以便IO线程不被阻塞):
private static final EventExecutorGroup handlersExecutor = new DefaultEventExecutorGroup(10);
...
pipeline.addLast(handlersExecutor, "authenticationHandler", new FrontendHandler(outboundAddress));
这个(=我做出的唯一更改!)会在负载测试期间使应用程序出现故障。导致什么问题?3500个客户端连接中的XXX个告诉我,这些客户端的500条消息中有YY条没有从代理服务器那里收到回复(每个请求都应该得到一条响应)。以下是客户端日志的摘录:
“2014年2月14日00:39:56.146 [id:0x34cb2c60]错误(com.nsn.ucpsimulator.common.UcpDecoder)-空闲连接(/ 127.0.0.1:7201)。接收到PDU:13” “2014年2月14日00:39:56.146 [id:0xf0955993]错误(com.nsn.ucpsimulator.common.UcpDecoder)-空闲连接(/ 127.0.0.1:7201)。接收到PDU:13” “2014年2月14日00:39:56.147 [id:0x9a911fa3]错误(com.nsn.ucpsimulator.common.UcpDecoder)-空闲连接(/ 127.0.0.1:7201)。接收到PDU:13” “2014年2月14日00:39:56.149 [id:0x811bbadf]错误(com.nsn.ucpsimulator.common.UcpDecoder)-空闲连接(/ 127.0.0.1:7201)。接收到PDU:13” “2014年2月14日00:39:56.150 [id:0x0c4d4c5a]错误(com.nsn.ucpsimulator.common.UcpDecoder)-空闲连接(/ 127.0.0.1:7201)。接收到PDU:13”
代理应用程序告诉我已经接收并转发了500条消息,但只收到了13条回复并转发回客户端。
2014-02-14 00:39:57.683 [id: 0x39af563b]错误(be.demmel.fun.UcpDecoder) - 空闲连接(/127.0.0.1:49359),接收到PDUs: 500 2014-02-14 00:39:57.683 [id: 0x82056d39]错误(be.demmel.fun.FrontendHandler) - 空闲连接(/127.0.0.1:52004),即将关闭,转发的PDUs: 500,成功数: 500 2014-02-14 00:40:00.717 [id: 0xcdca8f66]错误(be.demmel.fun.UcpDecoder) - 空闲连接(/127.0.0.1:7900),接收到PDUs: 13 2014-02-14 00:40:00.718 [id: 0xcdca8f66]错误(be.demmel.fun.BackendHandler) - 空闲连接(/127.0.0.1:7900),转发的PDUs: 13,成功数: 13
服务器告诉我一切正常: 2014-02-14 00:40:02.855 [id: 0x4980be2c]错误(com.nsn.ucpsimulator.common.UcpDecoder) - 空闲连接(/127.0.0.1:37944),接收到PDUs: 500 2014-02-14 00:40:02.856 [id: 0x4980be2c]错误(com.nsn.ucpsimulator.server.TestUcpHandler) - 空闲连接(/127.0.0.1:37944),返回的PDUs: 500
有人知道这是什么原因吗? 附加信息: 注意,使用单独的
EventExecutorGroup
作为阻塞处理程序时,一切正常。
每次XX个客户端阻塞时,它们都在转发到客户端的相同数量的答复处阻塞。
我已上传了Netty代码(其中包括代理、服务器和客户端应用程序以及README): https://github.com/AndrewBourgeois/ucp-proxy/tree/master/src/main/java/be/demmel/fun
当代理应用程序被杀死时,服务器端出现此错误:java.io.IOException: Connection reset by peer
at sun.nio.ch.FileDispatcherImpl.read0(Native Method) ~[na:1.7.0_45]
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39) ~[na:1.7.0_45]
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223) ~[na:1.7.0_45]
at sun.nio.ch.IOUtil.read(IOUtil.java:192) ~[na:1.7.0_45]
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:379) ~[na:1.7.0_45]
at io.netty.buffer.UnpooledUnsafeDirectByteBuf.setBytes(UnpooledUnsafeDirectByteBuf.java:401) ~[netty-all-4.0.9.Final.jar:na]
at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:869) ~[netty-all-4.0.9.Final.jar:na]
at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:208) ~[netty-all-4.0.9.Final.jar:na]
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:87) ~[netty-all-4.0.9.Final.jar:na]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:478) ~[netty-all-4.0.9.Final.jar:na]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:447) ~[netty-all-4.0.9.Final.jar:na]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:341) ~[netty-all-4.0.9.Final.jar:na]
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101) [netty-all-4.0.9.Final.jar:na]
at java.lang.Thread.run(Thread.java:744) [na:1.7.0_45]
我认为这个错误提示表明我的Netty处理程序没有处理服务器的回复。