我们的架构要求有两个并发工作流程:
我们得到了ClosedChannelException
,它似乎通过查看堆栈跟踪(Netty 3.7)来向执行者线程池传播错误。
java.nio.channels.ClosedChannelException
at sun.nio.ch.SocketChannelImpl.ensureWriteOpen(SocketChannelImpl.java:265)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:456)
at org.jboss.netty.channel.socket.nio.SocketSendBufferPool$UnpooledSendBuffer.transferTo(SocketSendBufferPool.java:203)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.write0(AbstractNioWorker.java:202)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromTaskLoop(AbstractNioWorker.java:152)
at org.jboss.netty.channel.socket.nio.AbstractNioChannel$WriteTask.run(AbstractNioChannel.java:335)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.processTaskQueue(AbstractNioSelector.java:366)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:290)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:90)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
我的问题是:
答案 0 :(得分:2)
它是否真的破坏了执行程序线程池?
没有
看来您的代码(可能是“将内容写入netty处理程序之外的netty频道”的东西)已经将频道关闭到了早期。 (正如@EJP评论的那样,这是你的代码中的一个错误......)
这不会破坏工作线程,但可能导致客户端发送了不完整的响应。
我担心的情况:一些写入旧封闭通道的数据和一个新创建的通道(重新连接到另一个地址),ClosedChannelException会搞砸吗?
旧的封闭频道与新频道无关。
如何在关闭和写入netty频道时处理这种并发?
重新设计您的代码,以便只有正常的Netty“工作流程”才会关闭频道。使两个“工作流程”共同负责关闭是一个问题的处方,特别是因为其中一个(正常的Netty工作流程)被硬编码为认为问题仅适用于它。
答案 1 :(得分:-1)
如果我是正确的,你也可以在自己的处理程序中获得异常。 我在处理程序中有这样的异常处理,因为出于多种原因可能会发生关闭连接,至少例如因为线路已断开连接(因此没有Netty或应用程序逻辑错误)。关闭的正常事件可能发生在您尝试向通道提交写入和异常之间。 在我的应用程序逻辑中,我考虑到了这一点,例如尝试重新连接,或者至少通过清理已关闭连接的上下文。
对我来说,这不是一个错误,但Netty必须通知您,您的应用程序处理程序对通道进行了关闭。